java - 使用数据库读写杀死多线程操作

标签 java linux multithreading hibernate exception

我有一个多线程 java 进程,运行 2 个数据库事务,如下所示:

.
.
dbop1();
.
.
.
dbop2();
.
.

当我终止进程(在 Linux 上使用 kill)时,数据库可能会失去完整性,因为程序可能会在 dbop1() 和 dbop2() 之间终止。
是否有办法捕获终止信号然后优雅地终止?例如,如果 kill 介于两者之间,我仍然希望完成 dbop2() 然后终止。

出于性能方面的考虑,我对在单个事务中进行 2 db 事务犹豫不决。 我假设如果 kill 在数据库事务期间发生,数据不会损坏,这是真的吗?
此外,dbop1() 和 dbop2() 是像下面这样的 hibernate 包装器:

    try{
            beginTransaction();
            getSession().save(obj);
            //sessionFactory.openSession().save(obj);
            commitTransaction();

        }
        catch(Exception e){
            e.printStackTrace();

            rollbackTransaction();
            throw e;
        }finally{
            closeSession(); 
        }

最佳答案

正如您已经提到的,这里正确的方法是将两个 db 语句都放在一个事务中,因为其他任何事情都很可能存在完整性问题。这可能取决于您的特定用例,但完整性问题通常比您在这里可能遇到的任何性能问题重要得多。

这超出了通过 kill 杀死应用程序的原因,因为第二个 db 语句可能有异常,应用程序可能在它们之间崩溃,或者服务器/网络可能有一个问题等等。所以最佳实践肯定是将两个语句放入一个事务中。

现在,综上所述,可以根据 kill 级别来阻止 kill 语句,也许可以通过注册一个等待(或阻止)直到两个语句完成的关闭 Hook 。但是,我不推荐这样做,因为 kill -9 会像上面提到的其他可能性一样完全跳过它。

例如(仅出于完整性考虑,因为我真的根本不推荐下面的代码)。 使用 ReentrantReadWriteLock 以某种方式通过 sharedState 共享(可以设置到下面的关闭 Hook 中,或者如果您真的愿意,它也可以是单例)。

Runtime.getRuntime.addShutdownHook(new Thread() {
    public void run()
    {
        sharedState.rwl.writeLock().lock();
        System.out.println("We are shutting down!");
        // Hopefully holding this lock does not prevent our shutdown
        // I.e. no other thread needs it to complete gracefully
    }
}

try
{
    sharedState.rwl.readLock().lock();
    dbOp1;
    dbOp2;
} finally
{
    sharedState.rwl.readLock().unlock();
}

其中 sharedState 代表某种机制,您可以通过该机制在关闭 Hook 和运行数据库操作的代码之间共享 rwl。

关于java - 使用数据库读写杀死多线程操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24899683/

相关文章:

java - 使用synchronized关键字和join()的输出差异

c - C 函数参数的意外行为

java - 如何协调多个类对私有(private)对象的同步

java - Perforce 链接文件

java - StringBuffer 与普通打印

java - spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults 有什么用?

linux - 安装 Arch 能否阻止我的笔记本电脑卡在启动屏幕上?

c++ - 将 PNG(包括 Alpha)与原始 ARGB 缓冲区混合的 C/C++ 库

android opengl es 在两个线程上运行的两个上下文之间共享纹理

asp.net - 网页中运行的线程