验证我对DB Locks和线程的理解

时间:2012-02-01 06:41:14

标签: 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          "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)

我有一个类,它在一个Transaction中获取一个表LOCK,在同一个代码块中,根据需要,我们需要启动一个新的事务,即将在同一个表上获取LOCK。在这种情况下,是否存在死锁的可能性,并且会因此Transaction Timeout异常而中断/解决。

此处的内部交易代码:

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过滤器中启动。

我的假设是内部事务正在等待外部事务获取的LOCK,并且外部事务正在等待完成执行该代码块以提交事务,在这种情况下,LOCK不会被释放,导致陷入僵局。最终,内部事务超时超时以打破僵局。

我的陈述有效吗?

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

希望你理解它,因为我不善于解释它!

1 个答案:

答案 0 :(得分:2)

  

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

  • 没有

如果是这样的话:

  

我有一个类启动一个Transaction,它在其中获取一个表LOCK,in   相同的代码块,根据要求,我们需要开始一个新的   似乎即将在同一张桌子上获得LOCK的交易

然后你似乎有一个基本的设计缺陷。

您需要保持较低限制的事务隔离级别,或重新设计逻辑(或两者都有)。