Java 验证我对DB锁和线程的理解

Java 验证我对DB锁和线程的理解,java,multithreading,oracle,transactions,Java,Multithreading,Oracle,Transactions,我在其中一个日志文件中观察到以下错误日志 2012-01-31 10:52:46,424 IST WARN "SQL Error: 2049, SQLState: 42000" 2012-01-31 10:52:46,424 IST ERROR "ORA-02049: timeout: distributed ransaction waiting for lock" 2012-01-31 10:52:46,440 IST ERROR "Co

我在其中一个日志文件中观察到以下错误日志

2012-01-31 10:52:46,424 IST WARN           "SQL Error: 2049, SQLState: 42000"
2012-01-31 10:52:46,424 IST ERROR          "ORA-02049: timeout: distributed ransaction waiting for lock"
2012-01-31 10:52:46,440 IST ERROR          "Could not synchronize database state with session"
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
我有一个类启动一个事务,它在同一个代码块中获得一个表锁,根据要求,我们需要启动一个新的事务,它将要在同一个表上获得锁。在这种情况下,存在死锁的可能性,死锁将通过此
事务超时
异常被打破/解决

此处为内部交易代码:

private void createXYZ(final Object tabPortletObject){

        try {
            //get the template
            TransactionTemplate transactionTemplate = getTransactionTemplate();
            //create a new transaction template with propagation behavior as requires new
            TransactionTemplate newTransactionTemplate = new TransactionTemplate();
            newTransactionTemplate.setTransactionManager(transactionTemplate.getTransactionManager());
            newTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            //start a new transaction and set the status in that new transaction
            newTransactionTemplate.execute(new TransactionCallbackWithoutResult() {
                public void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                    getHibernateTemplate().save(tabPortletObject);
                }
            });

        } catch (Exception e) {
            logger.info("Exception occured while creating [Tab/Portlet] :" + tabPortletObject);
        }
    }
我有一个外部事务,它将在servlet过滤器中启动

我的假设是,内部事务正在等待外部事务获取的锁,而外部事务正在等待完成执行该代码块以提交事务,在这种情况下,锁不会被释放,从而导致死锁。最终,内部事务将超时异常以打破该死锁

我的陈述有效吗

如果我在不同的线程中启动新的/内部事务,这可以解决吗

希望你能理解,因为我不擅长解释

“如果在不同线程中启动新的/内部事务,则可以解决此问题?”

  • 没有
如果这是真的:

我让一个类启动一个事务,在该事务中它得到一个表锁 同样的代码块,根据要求,我们需要开始一个新的 即将获取同一表上的锁的事务

那么你似乎有一个基本的设计缺陷


您要么需要保持一个限制较少的事务隔离级别,要么重新设计您的逻辑(或者两者都很糟糕)。

一个“分布式交易”——用干草叉和燃烧的火炬?;)我不明白为什么在那个段代码中需要2个事务。我不知道另一个开发人员在这里创建新事务的意图。他现在不在:)。我不明白你在top上的第一句话是什么意思?在oracle中锁定表通常是一种非常有缺陷的设计。为什么桌子需要锁上。我假设您不了解一致读取机制。@Pokuri,Match正在日志上注释,似乎缺少一个“t”。