java代码死锁导致事务无法提交

    前两天现场报流程无法下发,先看日志报错,是多线程造成的死锁:

<2016-1-27 下午03时08分59秒 GMT+08:00> <Error> <WebLogicServer> <BEA-000337> <[STUCK] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "606" seconds working on the request "weblogic.servlet.internal.ServletRequestImpl@77a4a3a4[

POST /web/aaa/bbb/plan/common/bpms/pmsBpmsOperateAction.do HTTP/1.1
Connection: keep-alive
Content-Length: 7620
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://10.150.22.1
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://10.150.22.1/web/aaa/bbb/plan/adjustplan/adjustplanaudit/audit/AdjustPlanSumAuditTodoList.jsp?listType=3
Accept-Encoding: gzip,deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: DWRSESSIONID=N3O6b25DRmadhrXc4E2$rYIT2al; JSESSIONIDMINI=DyMFWyqPrgJ3jnL1fpGLQt5qkQsBZc1nrVykqpv2xrtszDrN0Vqb!1710009500; BIGipServerpool_sys=152475146.53511.0000; ComtopSessionSID=<SNAID>DyMFWyqPrgJ3jnL1fpGLQt5qkQsBZc1nrVykqpv2xrtszDrN0Vqb!1710009500!1453877807674</SNAID>; cs_cStorage_=1; JSESSIONIDbbb=q0h5WyqCMZLk9LzVhGkLLKvRxvn2KtX2hT7LhVtHxW3LyGvpcR1c!10296795; BIGipServerpool_bbb=135697930.35603.0000
X-Forwarded-For: 10.122.8.83
]", which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:969)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1281)
java.util.concurrent.CountDownLatch.await(CountDownLatch.java:207)
com.comtop.aaa.bbb.plan.common.bpms.thread.ThreadBpmsUtil.execTread(ThreadBpmsUtil.java:170)
com.comtop.aaa.bbb.plan.common.bpms.thread.ThreadBpmsUtil.doBatchCommonFore(ThreadBpmsUtil.java:97)
com.comtop.aaa.bbb.plan.common.bpms.action.PmsBpmsOperateAction.doBatchCommonFore(PmsBpmsOperateAction.java:681)
com.comtop.aaa.bbb.plan.common.bpms.action.PmsBpmsOperateAction.handleBatchFore(PmsBpmsOperateAction.java:382)

查看数据库,可以看到堵塞的持有者是weblogic

 SELECT bs.username "Blocking User",
       bs.username "DB User",
       bs.SID "SID",
       bs.serial# "Serial#",
       bs.sql_address "address",
       bs.sql_hash_value "Sql hash",
       bs.program "Blocking App",  
       bs.machine "Blocking Machine",
       bs.osuser "Blocking OS User",
       bs.serial# "Serial#",                      
       ws.username "Waiting User",
       ws.SID "WSID",
       ws.program "Waiting App",
       ws.machine "Waiting Machine",
       ws.osuser "Waiting OS User",
       ws.serial# "WSerial#",
       wk.TYPE lock_type,
       hk.lmode mode_held,
       wk.request mode_requested,
       TO_CHAR(hk.id1) lock_id1,
       TO_CHAR(hk.id2) lock_id2,
       hk.BLOCK blocking_others
  FROM gv$lock hk, gv$session bs, gv$lock wk, gv$session ws
 WHERE hk.BLOCK = 1
   AND hk.lmode != 0
   AND hk.lmode != 1
   AND wk.request != 0
   AND wk.TYPE(+) = hk.TYPE
   AND wk.id1(+) = hk.id1
   AND wk.id2(+) = hk.id2
   AND hk.SID = bs.SID(+)
   AND wk.SID = ws.SID(+)
   AND (bs.username IS NOT NULL)
   AND (bs.username <> 'SYSTEM')
   AND (bs.username <> 'SYS')
 ORDER BY 1;
在数据库报告中,也看到相应的SQL:

Elapsed Time (s)ExecutionsElapsed Time per Exec (s)%Total%CPU%IOSQL IdSQL ModuleSQL Text
6,781.347,1800.947.720.060.9340dnpz84608j2JDBC Thin Clientxxxxx
4,589.0032214.255.2263.950.075tx8x8vavda6hJDBC Thin Clientxxxx.
4,327.2722,163.634.930.010.00apyz8h30zr2phJDBC Thin ClientUPDATE  PLAN_BATCH SET PLAN_...

### 回答1: 如果在 Java 中手动管理事务,并且不正确地使用事务,可能会导致事务锁表。这是因为在事务未正确提交或回滚时,数据库表上的锁将一直保持。这将阻止其他事务对该表进行操作,并可能导致性能问题和死锁。为了避免这种情况,应该及时提交或回滚事务,并使用合适的隔离级别。 ### 回答2: Java中的事务是一种用于确保数据库操作的原子性、一致性、隔离性和持久性的机制。手动事务是指在代码中通过编程方式控制事务的开始和结束,例如使用JDBC的beginTransaction()和commit()方法。 手动事务的使用需要谨慎,因为如果事务的操作时间过长,可能导致事务锁表的问题。长事务指的是事务持续执行的时间过长,导致其他会话无法访问或修改被锁定的资源。 长事务锁表的主要原因是事务在对某个表进行更新操作时,会获取并持有该表的锁,直到事务提交或回滚。如果事务执行的时间过长,其他会话就无法对同一表进行任何操作,从而导致阻塞。 为了避免长事务锁表问题,可以采取以下几种措施: 1. 尽量减少事务操作的时间,尽快释放锁定的资源。可以对事务中的操作进行性能优化,并使用合适的索引和查询优化技巧,以减少数据库操作的时间。 2. 合理选择事务的隔离级别。不同的隔离级别会对资源锁定的行为产生不同的影响。例如,使用Read Committed隔离级别可以减少锁定的范围,从而降低锁表的概率。 3. 控制事务的粒度。如果一个事务需要对多个表进行操作,可以将事务分为多个较小的事务,从而减少每个事务的执行时间和对资源的锁定。 4. 合理设置数据库的参数。例如,可以调整数据库的锁超时时间以及最大并发连接数等参数,以适应实际需求。 总之,虽然手动事务在控制数据库操作的同时提供了更大的灵活性,但需要在使用时注意事务的执行时间,避免长事务锁表问题的发生。同时也可以结合数据库的优化策略和调整参数,提高系统对长事务的容忍度。 ### 回答3: Java中的事务是一种用来管理数据库操作的机制,可以保证数据的一致性和完整性。但是,在手动管理事务的过程中,如果事务执行的时间过长,就可能会出现长事务锁表的问题。 当一个事务开始执行时,会获取所需的锁,以保证事务的原子性和一致性。在手动事务中,当开启一个事务后,所有的数据库操作都处于同一个事务中,直到事务提交或回滚。 如果在事务中执行的操作非常复杂,或者在事务中执行的查询、更新等操作的数据量非常大,就可能导致事务执行时间过长。这样的话,其他需要访问被锁定资源的操作只能等待事务完成才能继续执行,从而导致事务锁定表。 长事务锁表的问题可以通过以下几种方式来解决或缓解: 1. 优化事务操作:尽量减少事务执行的时间,可以考虑对复杂的操作进行优化,减少数据库的访问次数,降低锁定表的时间。 2. 拆分事务:将一个大的事务拆分成多个较小的事务,这样可以减少每个事务的执行时间,从而降低锁定表的时间。 3. 设置合适的隔离级别:在Java中,通过设置合适的事务隔离级别,可以在一定程度上降低锁定表的时间。可以根据需求选择适合的隔离级别,如读未提交、读已提交、可重复读、串行化等。 4. 合理规划事务边界:在应用程序设计中,合理规划事务的边界也是可以帮助缓解长事务锁表问题的。根据实际需求,将一次操作中可能发生的锁表问题拆分成多次操作,尽量减少长事务的出现。 总之,手动事务的长时间执行可能导致事务锁表问题。为了解决这个问题,可以对事务操作进行优化,拆分事务,设置合适的隔离级别,合理规划事务边界等。这些措施可以帮助缓解长事务锁表问题,提高系统的性能和响应速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值