- 浏览: 23505 次
- 性别:
- 来自: 深圳
最新评论
在 WebSphere JDBC Adapter 中如何避免死锁和锁超时
转自 http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1005_yuanjs_jdbcadapter_lock/
引言
WebSphere JDBC Adapter 是一个提供 J2EE 应用和数据库供应商的 EIS 解决方案之间的连接的资源适配器,是构建在 WebSphere Process Server 之上的 WebSphere Adapter。不用应用之间的数据交换发生在数据库层次,Adapter 使用 SQL 语句或存储过程以业务对象 (Business Object, BO) 的形式来传递数据,实现数据库与其他应用系统的集成。
WebSphere JDBC Adaper 可以集成任意构建在使用 JDBC 驱动(JDBC2.0 以上版本)的数据库上的企业应用,基于 J2EE JCA 技术实现了 JDBC API,提供了 Inbound 和 Outbound 两种操作来连接数据库。其中,在 Outbound 操作下,BO 从应用系统传递到数据库中,根据 BO 中指定的动作(Create, Update, Delete, Retrieve, , RetrieveAll, Execute, Exists),BO 作为一个请求发送到 Adapter 中,Adapter 将 BO 传递到具体数据库应用的表中。如果有需要,还可以进一步传递到其他构建在这个数据库之上的应用系统中,并进行相应处理。在 outbound 操作中,将会涉及到数据库的事务操作处理,继而会产生数据库的死锁和锁超时问题。接下来,看看死锁和锁超时分别在怎样的场景下会产生。
并发调用 WebSphere JDBC Adapter 的场景导致死锁现象
当 WebSphere JDBC Adapter 在 outbound 组件被并发调用的情况下,很可能产生死锁。在图 1 中,我们可以看到 outbound 组件的 create,delete 操作被并发的调用很多次。更为普遍的是,当多次发起用户请求的时候,会导致多线程场景。例如,outbound 组件在一个工作流中被使用,用户的多请求导致多个工作流并发的运行起来,也导致 outbound 组件也处在一个并发调用的情况下。
图 1. BPEL 中的并发情况
图 1:BPEL 中的并发情况
当 outbound 组件在并发调用比较高的情况下,会抛出下面死锁的异常信息:
清单 1. 死锁异常信息
[12/30/09 13:23:22:078 CST] 00000055 FFDC
Z com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl
com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl#0x04 Exception:
javax.resource.ResourceException: javax.resource.ResourceException:
DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001,
SQLERRMC=2, DRIVER=3.50.152, error code: -911
at com.ibm.j2ca.jdbc.commands.JDBCDeleteCommand.execute(JDBCDeleteCommand.java:379)
at com.ibm.j2ca.extension.commandpattern.CommandForCursor.execute
(CommandForCursor.java:68)
at com.ibm.j2ca.extension.commandpattern.Interpreter.
executeWithChildren(Interpreter.java:96)
at com.ibm.j2ca.extension.commandpattern.Interpreter.execute(Interpreter.java:77)
at com.ibm.j2ca.jdbc.JDBCInteraction.executeInternal(JDBCInteraction.java:358)
at com.ibm.j2ca.jdbc.JDBCInteraction.execute(JDBCInteraction.java:139)
at com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl.invoke(
J2CMethodBindingImpl.java:242)
在特定场景下产生锁超时
在图 2 的场景之下,WebSphere JDBC Adapter 产生的两个 outbound 组件加入到两个不同的 BPEL 组件中。在这两个 BPEL 组件中,“BPELGlobalTransaction”组件使用了全局事务,另外一个“BPELLocalTransaction”组件使用了本地事务。在 WebSphere JDBC Adapter 产生的这两个 outbound 组件中,使用全局事务的“globaltransaction”outbound 组件完成删除主键为“1”的记录的行为,另外一个使用本地事务的“localtransaction”outbound 组件则要完成创建一个主键为“1”的记录的行为。在这个场景中,使用了 DB2 数据库,其数据库参数死锁检查时间和锁超时检查时间分别是“10”秒和“120”秒:
Interval for checking deadlock (ms) (DLCHKTIME) = 10000
Lock timeout (sec) (LOCKTIMEOUT) = 120
图 2.在事务中运行的 WebSphere JDBC Adapter 的 outbound 组件
图 2 在事务中运行的 WebSphere JDBC Adapter 的 outbound 组件
“BPELGlobalTransaction”组件的内部业务逻辑比较复杂,在实际运行中要 5 分钟左右时间才能够完成。但是“BPELLocalTransaction”组件却比较简单,只需要几秒的时间就可以结束。首先启动“BPELGlobalTransaction”组件的运行,然后再启动“BPELLocalTransaction”组件的运行,大概 2 分多钟之后,WebSphere Process Server 报告如下锁超时的异常:
清单 1. 锁超时异常信息
[12/30/09 11:38:29:062 CST] 00000072 FFDC Z
com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl
com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl#0x04 Exception:
javax.resource.ResourceException:
DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001, SQLERRMC=68, DRIVER=3.50.152,
error code: -911
at com.ibm.j2ca.jdbc.JDBCDBOperationHandler.executePreparedCUDStatement
(JDBCDBOperationHandler.java:216)
at com.ibm.j2ca.jdbc.JDBCDBOperationHandler.executeSQL(
JDBCDBOperationHandler.java:646)
at com.ibm.j2ca.jdbc.commands.JDBCCreateCommand.execute(
JDBCCreateCommand.java:309)
at com.ibm.j2ca.extension.commandpattern.CommandForCursor.execute
(CommandForCursor.java:68)
at com.ibm.j2ca.extension.commandpattern.Interpreter.executeWithChildren
(Interpreter.java:96)
at com.ibm.j2ca.extension.commandpattern.Interpreter.execute(
Interpreter.java:77)
at com.ibm.j2ca.jdbc.JDBCInteraction.executeInternal(
JDBCInteraction.java:358)
at com.ibm.j2ca.jdbc.JDBCInteraction.execute(JDBCInteraction.java:139)
at com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl.invoke(
J2CMethodBindingImpl.java:242)
WebSphere Process Server 中 SCA 组件事务介绍
因为 WebSphere JDBC Adapter 运行在 WebSphere Process Server (WPS) 之上,其中对数据库事务的控制和管理则是由 WPS 负责完成的,所以必须先了解相关的 WPS 的组件事务知识。
WebSphere Process Server (WPS) 是建立在 WebSphere 应用服务器上的新一代业务集成平台。它支持面向服务的应用架构和企业服务总线,含有符合业界标准的业务流程引擎,使用统一的服务调用和业务表现模型,并遵循业界的开放标准。服务组件架构(Service Component Architecture,SCA)是 WPS 新的编程模型,为其提供了统一的服务调用模型,也提供完整的事务支持。图 3 是 SCA 的组件模型,一个 SCA 组件是由接口、服务实现和引用三个部分构成:
图 3.SCA 组件模型
图 3:SCA 组件模型
其中接口部分表示该组件能提供的业务能力;实现则是实现了该接口的组件;而引用则表示在服务实现中需要调用到的其他服务。在事务方面,SCA 通过在三个部分(接口、服务实现和引用)分别提供不同的限定符(qualifier)的方式来完成事务的定制。
图 4.接口上的事务限定符
图 4:接口上的事务限定符
图 4 显示了接口部分的限定符有:Join Transaction。可以取值 true 或者 false。这个限定符表示该组件是否愿意加入到调用方的事务中。
图 5. 实现上的事务限定符
图 5:实现上的事务限定符
图 5 显示了实现部分的限定符有:Transaction。 可以取值 Global、Local 或者 Any。这个限定符表示该组件对运行环境的需求。global 表示需要运行在一个全局事务中,这样 SCA 容器必须保证在调用该服务实现时总是有一个活动的全局事务。local 则表示要运行在本地事务中。容器必须挂起当前活动的全局事务,并负责启动一个本地事务。any 则表示该实现既可以运行在一个已有的全局事务中也可以运行在本地事务中。如果选择了 any,容器如果发现当前没有活动的事务,就会建立一个本地事务。
图 6. 引用上的事务限定符
图 6:引用上的事务限定符
图 6 显示了引用部分的限定符有:Suspend transaction。取值为 true 或者 false。用来表示在调用这个目标服务时是否需要把当前的全局事务挂起(但目标服务是否能加入到这个事务中,还取决于目标服务的事务配置)。如果选择 true,则表示当前服务的事务不会被传播给所调用的服务。这个限定符只针对同步调用有效。
通过这三个部分的组合就可以实现细粒度的事务控制,这样也就能对各个组件实现更为精确的事务控制。下面的表格 1 列举出 Join transaction 和 transaction 两种选项组合的情况下,如何实现对事务的管理和实现。
表 1. 目标组件的事务行为
接口
“Join Transaction”qualifier
实现
“Transaction” qualifier
目标组件的事务行为
True Global 如果目标组件已有全局事务的上下文环境,那么目标组件就参与到已有全局事务中去;否则,运行时产生一个新的全局事务。
True Local 运行时产生一个错误,这个限定符的设置不对。
True Any 如果目标组件已有全局事务的上下文环境,那么目标组件就参与到已有全局事务中去;否则,运行时产生一个新的本地事务。
False Global 目标组件运行在全局事务中,总是产生一个新的全局事务。
False Local 目标组件运行在本地事务中。
False Any 目标组件运行在本地事务中。
下面给一个具体例子,比如一个 SCA 组件有如下的事务需求:在运行时候需要有全局事务但不能加入到已有的全局事务中,该组件需要调用到其他的服务,希望其他的服务也能加入到自己的事务中。那么应该如下设计 :
•接口的事务限定符应该设置为 join transaction=false,这样就防止了该组件加入到上游的事务中;
•实现上的事务限定符应该设置为 transaction=global。这样 SCA 容器在调用该实现之前就会启动一个全局事务;
•引用上的事务限定符应该设置为 suspend transaction=false。这样组件实现的事务就被允许传播到被调用的服务;
WebSphere JDBC Adapter 中 outbound 组件事务介绍
WebSphere JDBC Adapter 的 outbound 组件只能在接口上进行事务限定符的配置,不可以在实现和引用上进行事务限定符的设置。
图 7. WebSphere JDBC Adapter 的 outbound 组件上的事务限定符
图 7:WebSphere JDBC Adapter 的 outbound 组件上的事务限定符
在图 7 中,WebSphere JDBC Adapter 只有接口上的事务限定符的设置,没有提供实现和引用上的事务限定符的设置。从这点上来看,它既符合了 SCA 组件的事务限定符的规则,同时又有它自己的特殊性。
此外,WebSphere JDBC Adapter 提供了三种连接方式,分别是“database URL mode”,“datasource JNDI mode”,“XA datasource name mode”。它们和 WebSphere JDBC Adapter 的 outbound 组件的事务有着很紧密的联系。图 8 中显示了上面三种连接方式。
图 8. WebSphere JDBC Adapter 的连接方式
图 8:WebSphere JDBC Adapter 的连接方式
WebSphere JDBC Adapter 根据接口上的事务限定符和三种连接方式确定 outbound 组件的事务行为,表格 2 中描述了各种组合之下产生的事务行为。
表 2:WebSphere JDBC Adapter 的 outbound 组件的事务行为
接口
“Join Transaction” qualifier
Outbound 组件采用的连接方式
outbound 组件的事务行为
True 1.使用“datasource JNDI mode”连接方式,且 datasource 是非 XA。
2.或者使用“database URL mode”的连接方式。
运行时产生一个错误,这个限定符的设置不对。
False 1.使用“datasource JNDI mode”连接方式,且 datasource 是非 XA。
2.或者使用“database URL mode”的连接方式。
outbound 组件运行在本地事务中。
True 1.使用“datasource JNDI mode”连接方式,且 datasource 是 XA。
2.或者使用“XA datasource name mode” 连接方式(仅适用于 DB2,Oracle 数据库)。
如果 outbound 组件已有全局事务的上下文环境,那么 outbound 组件就参与到已有全局事务中去;否则,运行时产生一个新的全局事务。
False 1.使用“datasource JNDI mode”连接方式,且 datasource 是 XA。
2.或者使用“XA datasource name mode”连接方式(仅适用于 DB2,Oracle 数据库)
outbound 组件运行在本地事务中。
表格 2 中,当接口上的事务限定符是“join transaction=true”,同时采用“datasource JNDI mode”连接方式,且 WPS 上的 datasource 是 XA 类型的时候,它会在全局事务下运行;当接口上的事务限定符是“join transaction=false”,同时采用“datasource JNDI mode”连接方式,且 WPS 的 datasource 是 XA 类型的时候,它则会在本地事务下运行。
在了解了 WPS 的组件事务和 WebSphere JDBC Adapter 的 outbound 组件知识之后,接下来进一步分析死锁和锁超时是如何产生的。
死锁是如何产生的
WebSphere JDBC Adapter 在并发情况下产生数据库死锁现象,仅仅出现在它采用“datasource JNDI mode”连接方式的时候。在“datasource JNDI mode”连接方式下,WebSphere JDBC Adapter 使用了 WPS 的 Data Source。这个 Data Source 连接数据库的时候,事务隔离级别是被 WPS 的 Data Source 控制的,WebSphere JDBC Adapter 并没有提供对事务隔离级别的控制。在缺省情况下,连接 DB2 和 MSSQLServer 的时候,WPS 上的 Data Source 事务隔离级别在被设置在“TRANSACTION_REPEATABLE_READ”下;在连接 Oracle 的时候,WPS 上的 Data Source 事务隔离级别在被设置在“TRANSACTION_READ_COMMITTED”下。同时,DB2、MSSQLServer、Oracle 数据库端的缺省事务隔离级别都是“TRANSACTION_READ_COMMITTED”。WPS 上的 Data Source 事务隔离级别优先级别高于数据库端的隔离级别,所以当使用 WebSphere JDBC Adapter 的“datasource JNDI mode”连接方式去访问 DB2 和 MSSQLServer 数据库的时候,所产生的数据库连接总是在“TRANSACTION_REPEATABLE_READ”事务隔离级别下,它对事务的一致性和完整性要求比较高,会有死锁现象的发生;但是,访问 Oracle 数据库的时候,所产生的数据库连接则是在“TRANSACTION_READ_COMMITTED”事务隔离级别下,不要求高的事务一致性和完整性,不会有死锁现象的发生。总之,在 WebSphere JDBC Adapter 被并发调用和在较高的事务隔离级别使用的情况下,会对数据库中被访问的表和行产生很多锁,以及出现锁升级的情况,从而导致死锁现象的发生。如果事务隔离级别设置的越高,数据完整性就越高,对并发支持和性能就会降低;如果事务隔离级别设置的越低,对并发支持和性能提高越好,但是数据完整性就会降低。
如何解决死锁问题
要解决死锁问题,可以通过更改数据库连接的事务隔离级别来达到消除死锁现象的发生,具体的更改措施有如下几种。
•更改 WPS 上 Data Source 的缺省事务隔离级别,将缺省的“TRANSACTION_REPEATABLE_READ”事务隔离级别降低到“TRANSACTION_READ_COMMITTED”,详情请查阅“参考资料”一节。
•更改 SCA component 上 EJB 的事务隔离级别,详情请查阅“参考资料”一节。
当 WPS 上的 Data Source 事务隔离级别降低之后,应用程序对并发的支持和性能提高了,从而也就避免数据库死锁现象的发生。
锁超时是怎么产生的
在图 2 场景中,DB2 数据库端的死锁检查时间是 10 秒,锁超时检查时间是 120 秒,也就是说,在数据库端,每过 10 秒中要检查数据库中是否存在死锁现象,每过 2 分钟要检查是否有锁超时现象。在“globaltransaction”outbound 组件中,当它要执行删除主键为“1”的记录的时候,因为同时它已加入到了“BPELGlobalTransaction”组件发起的全局事务中去,所以它必须等待这个 BPEL 组件所有业务逻辑操作全部都执行完毕,这个删除的操作才能最终提交到数据库中去。在没有执行完 BPEL 组件中所有的业务逻辑前,这个删除操作一直不能提交到数据库。这会导致主键为“1”的记录在数据库上被锁住不放。在这个场景中,由于这个“BPELGlobalTransaction”组件执行完成需要 5 分钟的时间,所以数据库会将这条主键为“1”的记录锁住 5 分钟不放直至业务逻辑完成为止。当这条主键为“1”的记录被锁住的同时,第二个“BPELLocalTransaction”组件也启动了,它需要调用“localtransaction”outbound 组件执行创建主键为“1”的记录,此时数据库会检测到这个记录正在被另外一个应用锁住了,所以“BPELLocalTransaction”组件不得不等待在这条记录上锁的释放,过了 2 分钟以后,数据库检查到这个锁仍然没有释放,但是锁超时的时间已经到达,所以 WPS 报告锁超时异常,终止“localtransaction”组件创建记录的操作。通过以上分析,如果 WebSphere JDBC Adapter 产生的 outbound 组件加入到一个全局事务中后,全局事务的时间过长会产生锁超时的异常。
如何解决锁超时问题
在上节的锁超时问题分析中,因为 WebSphere JDBC Adapter 的一个 outbound 组件加入到上游组件的全局事务中去,且很可能这个上游组件的全局事务执行完成所需要的时间超过了数据库锁超时的时间,在这种情况之下,又出现了其他的 WebSphere JDBC Adapter 的 outbound 组件也要访问这个全局事务中已经访问过的记录,此刻就会出现锁超时现象。为了避免这种现象,从设计上就要考虑,应该尽可能的使得全局事务消耗的时间要短,在不同应用中要避免访问相同的表或者记录。当然,适当调整数据库锁超时时间也是可行方法之一。
总结
本文首先引入在 WebSphere JDBC Adapter 上产生死锁和锁超时的场景,然后介绍了 WPS 中 SCA 组件的事务特性,接着论述了 WebSphere JDBC Adapter 的 outbound 组件事务的特别之处,然后在实际应用中,针对事务引发的死锁和锁超时的现象寻找原因和进行分析,最后提供了解决办法去避免死锁和锁超时现象。
转自 http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1005_yuanjs_jdbcadapter_lock/
引言
WebSphere JDBC Adapter 是一个提供 J2EE 应用和数据库供应商的 EIS 解决方案之间的连接的资源适配器,是构建在 WebSphere Process Server 之上的 WebSphere Adapter。不用应用之间的数据交换发生在数据库层次,Adapter 使用 SQL 语句或存储过程以业务对象 (Business Object, BO) 的形式来传递数据,实现数据库与其他应用系统的集成。
WebSphere JDBC Adaper 可以集成任意构建在使用 JDBC 驱动(JDBC2.0 以上版本)的数据库上的企业应用,基于 J2EE JCA 技术实现了 JDBC API,提供了 Inbound 和 Outbound 两种操作来连接数据库。其中,在 Outbound 操作下,BO 从应用系统传递到数据库中,根据 BO 中指定的动作(Create, Update, Delete, Retrieve, , RetrieveAll, Execute, Exists),BO 作为一个请求发送到 Adapter 中,Adapter 将 BO 传递到具体数据库应用的表中。如果有需要,还可以进一步传递到其他构建在这个数据库之上的应用系统中,并进行相应处理。在 outbound 操作中,将会涉及到数据库的事务操作处理,继而会产生数据库的死锁和锁超时问题。接下来,看看死锁和锁超时分别在怎样的场景下会产生。
并发调用 WebSphere JDBC Adapter 的场景导致死锁现象
当 WebSphere JDBC Adapter 在 outbound 组件被并发调用的情况下,很可能产生死锁。在图 1 中,我们可以看到 outbound 组件的 create,delete 操作被并发的调用很多次。更为普遍的是,当多次发起用户请求的时候,会导致多线程场景。例如,outbound 组件在一个工作流中被使用,用户的多请求导致多个工作流并发的运行起来,也导致 outbound 组件也处在一个并发调用的情况下。
图 1. BPEL 中的并发情况
图 1:BPEL 中的并发情况
当 outbound 组件在并发调用比较高的情况下,会抛出下面死锁的异常信息:
清单 1. 死锁异常信息
[12/30/09 13:23:22:078 CST] 00000055 FFDC
Z com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl
com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl#0x04 Exception:
javax.resource.ResourceException: javax.resource.ResourceException:
DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001,
SQLERRMC=2, DRIVER=3.50.152, error code: -911
at com.ibm.j2ca.jdbc.commands.JDBCDeleteCommand.execute(JDBCDeleteCommand.java:379)
at com.ibm.j2ca.extension.commandpattern.CommandForCursor.execute
(CommandForCursor.java:68)
at com.ibm.j2ca.extension.commandpattern.Interpreter.
executeWithChildren(Interpreter.java:96)
at com.ibm.j2ca.extension.commandpattern.Interpreter.execute(Interpreter.java:77)
at com.ibm.j2ca.jdbc.JDBCInteraction.executeInternal(JDBCInteraction.java:358)
at com.ibm.j2ca.jdbc.JDBCInteraction.execute(JDBCInteraction.java:139)
at com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl.invoke(
J2CMethodBindingImpl.java:242)
在特定场景下产生锁超时
在图 2 的场景之下,WebSphere JDBC Adapter 产生的两个 outbound 组件加入到两个不同的 BPEL 组件中。在这两个 BPEL 组件中,“BPELGlobalTransaction”组件使用了全局事务,另外一个“BPELLocalTransaction”组件使用了本地事务。在 WebSphere JDBC Adapter 产生的这两个 outbound 组件中,使用全局事务的“globaltransaction”outbound 组件完成删除主键为“1”的记录的行为,另外一个使用本地事务的“localtransaction”outbound 组件则要完成创建一个主键为“1”的记录的行为。在这个场景中,使用了 DB2 数据库,其数据库参数死锁检查时间和锁超时检查时间分别是“10”秒和“120”秒:
Interval for checking deadlock (ms) (DLCHKTIME) = 10000
Lock timeout (sec) (LOCKTIMEOUT) = 120
图 2.在事务中运行的 WebSphere JDBC Adapter 的 outbound 组件
图 2 在事务中运行的 WebSphere JDBC Adapter 的 outbound 组件
“BPELGlobalTransaction”组件的内部业务逻辑比较复杂,在实际运行中要 5 分钟左右时间才能够完成。但是“BPELLocalTransaction”组件却比较简单,只需要几秒的时间就可以结束。首先启动“BPELGlobalTransaction”组件的运行,然后再启动“BPELLocalTransaction”组件的运行,大概 2 分多钟之后,WebSphere Process Server 报告如下锁超时的异常:
清单 1. 锁超时异常信息
[12/30/09 11:38:29:062 CST] 00000072 FFDC Z
com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl
com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl#0x04 Exception:
javax.resource.ResourceException:
DB2 SQL Error: SQLCODE=-911, SQLSTATE=40001, SQLERRMC=68, DRIVER=3.50.152,
error code: -911
at com.ibm.j2ca.jdbc.JDBCDBOperationHandler.executePreparedCUDStatement
(JDBCDBOperationHandler.java:216)
at com.ibm.j2ca.jdbc.JDBCDBOperationHandler.executeSQL(
JDBCDBOperationHandler.java:646)
at com.ibm.j2ca.jdbc.commands.JDBCCreateCommand.execute(
JDBCCreateCommand.java:309)
at com.ibm.j2ca.extension.commandpattern.CommandForCursor.execute
(CommandForCursor.java:68)
at com.ibm.j2ca.extension.commandpattern.Interpreter.executeWithChildren
(Interpreter.java:96)
at com.ibm.j2ca.extension.commandpattern.Interpreter.execute(
Interpreter.java:77)
at com.ibm.j2ca.jdbc.JDBCInteraction.executeInternal(
JDBCInteraction.java:358)
at com.ibm.j2ca.jdbc.JDBCInteraction.execute(JDBCInteraction.java:139)
at com.ibm.ws.sca.internal.j2c.J2CMethodBindingImpl.invoke(
J2CMethodBindingImpl.java:242)
WebSphere Process Server 中 SCA 组件事务介绍
因为 WebSphere JDBC Adapter 运行在 WebSphere Process Server (WPS) 之上,其中对数据库事务的控制和管理则是由 WPS 负责完成的,所以必须先了解相关的 WPS 的组件事务知识。
WebSphere Process Server (WPS) 是建立在 WebSphere 应用服务器上的新一代业务集成平台。它支持面向服务的应用架构和企业服务总线,含有符合业界标准的业务流程引擎,使用统一的服务调用和业务表现模型,并遵循业界的开放标准。服务组件架构(Service Component Architecture,SCA)是 WPS 新的编程模型,为其提供了统一的服务调用模型,也提供完整的事务支持。图 3 是 SCA 的组件模型,一个 SCA 组件是由接口、服务实现和引用三个部分构成:
图 3.SCA 组件模型
图 3:SCA 组件模型
其中接口部分表示该组件能提供的业务能力;实现则是实现了该接口的组件;而引用则表示在服务实现中需要调用到的其他服务。在事务方面,SCA 通过在三个部分(接口、服务实现和引用)分别提供不同的限定符(qualifier)的方式来完成事务的定制。
图 4.接口上的事务限定符
图 4:接口上的事务限定符
图 4 显示了接口部分的限定符有:Join Transaction。可以取值 true 或者 false。这个限定符表示该组件是否愿意加入到调用方的事务中。
图 5. 实现上的事务限定符
图 5:实现上的事务限定符
图 5 显示了实现部分的限定符有:Transaction。 可以取值 Global、Local 或者 Any。这个限定符表示该组件对运行环境的需求。global 表示需要运行在一个全局事务中,这样 SCA 容器必须保证在调用该服务实现时总是有一个活动的全局事务。local 则表示要运行在本地事务中。容器必须挂起当前活动的全局事务,并负责启动一个本地事务。any 则表示该实现既可以运行在一个已有的全局事务中也可以运行在本地事务中。如果选择了 any,容器如果发现当前没有活动的事务,就会建立一个本地事务。
图 6. 引用上的事务限定符
图 6:引用上的事务限定符
图 6 显示了引用部分的限定符有:Suspend transaction。取值为 true 或者 false。用来表示在调用这个目标服务时是否需要把当前的全局事务挂起(但目标服务是否能加入到这个事务中,还取决于目标服务的事务配置)。如果选择 true,则表示当前服务的事务不会被传播给所调用的服务。这个限定符只针对同步调用有效。
通过这三个部分的组合就可以实现细粒度的事务控制,这样也就能对各个组件实现更为精确的事务控制。下面的表格 1 列举出 Join transaction 和 transaction 两种选项组合的情况下,如何实现对事务的管理和实现。
表 1. 目标组件的事务行为
接口
“Join Transaction”qualifier
实现
“Transaction” qualifier
目标组件的事务行为
True Global 如果目标组件已有全局事务的上下文环境,那么目标组件就参与到已有全局事务中去;否则,运行时产生一个新的全局事务。
True Local 运行时产生一个错误,这个限定符的设置不对。
True Any 如果目标组件已有全局事务的上下文环境,那么目标组件就参与到已有全局事务中去;否则,运行时产生一个新的本地事务。
False Global 目标组件运行在全局事务中,总是产生一个新的全局事务。
False Local 目标组件运行在本地事务中。
False Any 目标组件运行在本地事务中。
下面给一个具体例子,比如一个 SCA 组件有如下的事务需求:在运行时候需要有全局事务但不能加入到已有的全局事务中,该组件需要调用到其他的服务,希望其他的服务也能加入到自己的事务中。那么应该如下设计 :
•接口的事务限定符应该设置为 join transaction=false,这样就防止了该组件加入到上游的事务中;
•实现上的事务限定符应该设置为 transaction=global。这样 SCA 容器在调用该实现之前就会启动一个全局事务;
•引用上的事务限定符应该设置为 suspend transaction=false。这样组件实现的事务就被允许传播到被调用的服务;
WebSphere JDBC Adapter 中 outbound 组件事务介绍
WebSphere JDBC Adapter 的 outbound 组件只能在接口上进行事务限定符的配置,不可以在实现和引用上进行事务限定符的设置。
图 7. WebSphere JDBC Adapter 的 outbound 组件上的事务限定符
图 7:WebSphere JDBC Adapter 的 outbound 组件上的事务限定符
在图 7 中,WebSphere JDBC Adapter 只有接口上的事务限定符的设置,没有提供实现和引用上的事务限定符的设置。从这点上来看,它既符合了 SCA 组件的事务限定符的规则,同时又有它自己的特殊性。
此外,WebSphere JDBC Adapter 提供了三种连接方式,分别是“database URL mode”,“datasource JNDI mode”,“XA datasource name mode”。它们和 WebSphere JDBC Adapter 的 outbound 组件的事务有着很紧密的联系。图 8 中显示了上面三种连接方式。
图 8. WebSphere JDBC Adapter 的连接方式
图 8:WebSphere JDBC Adapter 的连接方式
WebSphere JDBC Adapter 根据接口上的事务限定符和三种连接方式确定 outbound 组件的事务行为,表格 2 中描述了各种组合之下产生的事务行为。
表 2:WebSphere JDBC Adapter 的 outbound 组件的事务行为
接口
“Join Transaction” qualifier
Outbound 组件采用的连接方式
outbound 组件的事务行为
True 1.使用“datasource JNDI mode”连接方式,且 datasource 是非 XA。
2.或者使用“database URL mode”的连接方式。
运行时产生一个错误,这个限定符的设置不对。
False 1.使用“datasource JNDI mode”连接方式,且 datasource 是非 XA。
2.或者使用“database URL mode”的连接方式。
outbound 组件运行在本地事务中。
True 1.使用“datasource JNDI mode”连接方式,且 datasource 是 XA。
2.或者使用“XA datasource name mode” 连接方式(仅适用于 DB2,Oracle 数据库)。
如果 outbound 组件已有全局事务的上下文环境,那么 outbound 组件就参与到已有全局事务中去;否则,运行时产生一个新的全局事务。
False 1.使用“datasource JNDI mode”连接方式,且 datasource 是 XA。
2.或者使用“XA datasource name mode”连接方式(仅适用于 DB2,Oracle 数据库)
outbound 组件运行在本地事务中。
表格 2 中,当接口上的事务限定符是“join transaction=true”,同时采用“datasource JNDI mode”连接方式,且 WPS 上的 datasource 是 XA 类型的时候,它会在全局事务下运行;当接口上的事务限定符是“join transaction=false”,同时采用“datasource JNDI mode”连接方式,且 WPS 的 datasource 是 XA 类型的时候,它则会在本地事务下运行。
在了解了 WPS 的组件事务和 WebSphere JDBC Adapter 的 outbound 组件知识之后,接下来进一步分析死锁和锁超时是如何产生的。
死锁是如何产生的
WebSphere JDBC Adapter 在并发情况下产生数据库死锁现象,仅仅出现在它采用“datasource JNDI mode”连接方式的时候。在“datasource JNDI mode”连接方式下,WebSphere JDBC Adapter 使用了 WPS 的 Data Source。这个 Data Source 连接数据库的时候,事务隔离级别是被 WPS 的 Data Source 控制的,WebSphere JDBC Adapter 并没有提供对事务隔离级别的控制。在缺省情况下,连接 DB2 和 MSSQLServer 的时候,WPS 上的 Data Source 事务隔离级别在被设置在“TRANSACTION_REPEATABLE_READ”下;在连接 Oracle 的时候,WPS 上的 Data Source 事务隔离级别在被设置在“TRANSACTION_READ_COMMITTED”下。同时,DB2、MSSQLServer、Oracle 数据库端的缺省事务隔离级别都是“TRANSACTION_READ_COMMITTED”。WPS 上的 Data Source 事务隔离级别优先级别高于数据库端的隔离级别,所以当使用 WebSphere JDBC Adapter 的“datasource JNDI mode”连接方式去访问 DB2 和 MSSQLServer 数据库的时候,所产生的数据库连接总是在“TRANSACTION_REPEATABLE_READ”事务隔离级别下,它对事务的一致性和完整性要求比较高,会有死锁现象的发生;但是,访问 Oracle 数据库的时候,所产生的数据库连接则是在“TRANSACTION_READ_COMMITTED”事务隔离级别下,不要求高的事务一致性和完整性,不会有死锁现象的发生。总之,在 WebSphere JDBC Adapter 被并发调用和在较高的事务隔离级别使用的情况下,会对数据库中被访问的表和行产生很多锁,以及出现锁升级的情况,从而导致死锁现象的发生。如果事务隔离级别设置的越高,数据完整性就越高,对并发支持和性能就会降低;如果事务隔离级别设置的越低,对并发支持和性能提高越好,但是数据完整性就会降低。
如何解决死锁问题
要解决死锁问题,可以通过更改数据库连接的事务隔离级别来达到消除死锁现象的发生,具体的更改措施有如下几种。
•更改 WPS 上 Data Source 的缺省事务隔离级别,将缺省的“TRANSACTION_REPEATABLE_READ”事务隔离级别降低到“TRANSACTION_READ_COMMITTED”,详情请查阅“参考资料”一节。
•更改 SCA component 上 EJB 的事务隔离级别,详情请查阅“参考资料”一节。
当 WPS 上的 Data Source 事务隔离级别降低之后,应用程序对并发的支持和性能提高了,从而也就避免数据库死锁现象的发生。
锁超时是怎么产生的
在图 2 场景中,DB2 数据库端的死锁检查时间是 10 秒,锁超时检查时间是 120 秒,也就是说,在数据库端,每过 10 秒中要检查数据库中是否存在死锁现象,每过 2 分钟要检查是否有锁超时现象。在“globaltransaction”outbound 组件中,当它要执行删除主键为“1”的记录的时候,因为同时它已加入到了“BPELGlobalTransaction”组件发起的全局事务中去,所以它必须等待这个 BPEL 组件所有业务逻辑操作全部都执行完毕,这个删除的操作才能最终提交到数据库中去。在没有执行完 BPEL 组件中所有的业务逻辑前,这个删除操作一直不能提交到数据库。这会导致主键为“1”的记录在数据库上被锁住不放。在这个场景中,由于这个“BPELGlobalTransaction”组件执行完成需要 5 分钟的时间,所以数据库会将这条主键为“1”的记录锁住 5 分钟不放直至业务逻辑完成为止。当这条主键为“1”的记录被锁住的同时,第二个“BPELLocalTransaction”组件也启动了,它需要调用“localtransaction”outbound 组件执行创建主键为“1”的记录,此时数据库会检测到这个记录正在被另外一个应用锁住了,所以“BPELLocalTransaction”组件不得不等待在这条记录上锁的释放,过了 2 分钟以后,数据库检查到这个锁仍然没有释放,但是锁超时的时间已经到达,所以 WPS 报告锁超时异常,终止“localtransaction”组件创建记录的操作。通过以上分析,如果 WebSphere JDBC Adapter 产生的 outbound 组件加入到一个全局事务中后,全局事务的时间过长会产生锁超时的异常。
如何解决锁超时问题
在上节的锁超时问题分析中,因为 WebSphere JDBC Adapter 的一个 outbound 组件加入到上游组件的全局事务中去,且很可能这个上游组件的全局事务执行完成所需要的时间超过了数据库锁超时的时间,在这种情况之下,又出现了其他的 WebSphere JDBC Adapter 的 outbound 组件也要访问这个全局事务中已经访问过的记录,此刻就会出现锁超时现象。为了避免这种现象,从设计上就要考虑,应该尽可能的使得全局事务消耗的时间要短,在不同应用中要避免访问相同的表或者记录。当然,适当调整数据库锁超时时间也是可行方法之一。
总结
本文首先引入在 WebSphere JDBC Adapter 上产生死锁和锁超时的场景,然后介绍了 WPS 中 SCA 组件的事务特性,接着论述了 WebSphere JDBC Adapter 的 outbound 组件事务的特别之处,然后在实际应用中,针对事务引发的死锁和锁超时的现象寻找原因和进行分析,最后提供了解决办法去避免死锁和锁超时现象。
发表评论
-
启动Tomcat启动不了,报以下错:Error listenerStart解决方法
2016-09-04 15:35 496启动Tomcat启动不了,报以下错: org.apach ... -
java自定义标签库的开发
2016-04-08 17:45 0java自定义标签库的开发 :http://www.360 ... -
sitemesh技术的应用
2016-03-23 13:55 490sitemesh技术的应用 ... -
java爬虫gecco监控来了,不再裸奔
2016-03-21 15:05 0java爬虫gecco监控来了,不再裸奔 爬虫为什么要监控 ... -
Eclipse快捷键 10个最有用的快捷键
2016-03-12 16:28 0Eclipse中10个最有用的快捷键组合 一个Eclip ... -
JAVA 注解的几大作用及使用方法详解
2016-01-13 15:26 0JAVA 注解的几大作用及使用方法详解(2013- ... -
java内存溢出分析
2016-01-12 18:03 411用jmap生产dump文件,win通过任务管理器查看to ... -
java垃圾回收
2016-01-12 13:42 468 -
java内存泄露
2016-01-12 10:19 0用Eclipse Memory Analyzer查找内存泄露: ... -
计算机网络
2016-01-11 17:12 0计算机网络体系结构:http://henu-zyy.iteye ... -
spring MVC
2016-01-11 15:59 0国际化、本地化及Spring MVC 的设计:http://c ... -
服务器缓存技术
2016-01-11 11:45 0缓存使用与设计系列文章--目录:http://carlosfu ... -
java JFrame关闭窗口最大化功能
2015-06-18 10:05 2083如是JFrame框架,直接设置: JFrame jf = ne ... -
一些JAVA代码功能的相关链接
2015-06-18 09:04 0spring集成quartz任务调度: http://aton ... -
jsp页面静态化例子
2015-06-17 11:20 728连接:http://konglx.iteye.com/blog ... -
JFrame实现窗体在屏幕边缘靠边隐藏
2015-06-16 14:30 1119用JAVA swing做一个项目,类似QQ实现靠边隐藏的代码记 ... -
如何在JAVA程序中注册热键
2015-06-08 17:37 633http://walsece.iteye.com/blog/1 ... -
DB2锁表信息
2015-06-01 18:24 488查看数据库锁表信息 ----查询数据库锁表信息 db2 &qu ... -
转:apache安装后no service install解决办法
2015-05-31 17:01 545以下是解决步骤: 1、找到 apache2 目录下的 ... -
WAS 节点不同步解决办法一
2015-05-26 20:29 1513WAS 节点不同步解决办法一 博客分类: 应用服务器 ...
相关推荐
在企业级应用集成中,WebSphere JDBC Adapter 是一个强大的工具,它允许应用程序通过标准的 Java Database Connectivity (JDBC) API 与各种数据源进行交互。本文将深入探讨如何扩展 WebSphere JDBC Adapter,以实现...
以上就是在WebSphere中创建JDBC数据源和部署项目的详细步骤。每个步骤都需要谨慎操作,以确保数据源的稳定性和应用的正常运行。在实际环境中,可能还需要考虑安全性、性能调优和其他高级特性,但这些基本步骤为理解...
在WebSphere应用服务器中,建立JDBC数据源是连接到数据库的关键步骤,它允许应用程序通过Java Database Connectivity (JDBC) API与数据库进行交互。以下是一个详细的步骤指南: 1. **启动WebSphere服务**: - 找到...
在配置JDBC与WebSphere的过程中,安全性和认证是非常重要的考虑因素。WAS支持多种安全模型,包括基于用户ID和密码的身份验证机制,以及更为复杂的集成安全认证方案。开发者需要根据具体的应用场景选择合适的安全策略...
根据提供的文件信息,“Adapter for JDBC User Guide”主要介绍了IBM WebSphere Business Integration Adapters中的JDBC Adapter的使用方法及相关特性。本文将对这份指南的关键知识点进行详细的解析与介绍。 ### ...
Websphere是一个由IBM开发的企业级应用服务器,广泛用于构建和部署各种企业级应用程序。在Websphere的管理和配置过程中,安全性和权限控制是至关重要的环节,其中就包括了密码管理。有时候,由于各种原因,管理员...
在IBM WebSphere Application Server 6.1中配置JDBC数据源是将应用程序连接到数据库的关键步骤。这个过程涉及创建和配置JDBC提供程序、数据源以及相关的认证别名,以确保应用程序能够顺利地访问和操作数据库。以下是...
通过以上步骤,用户不仅可以顺利完成 WebSphere Application Server 的安装和配置,还可以在 MyEclipse 中有效地部署 Java 应用程序。这一系列的操作虽然繁琐,但对于搭建稳定高效的企业级应用平台至关重要。在实际...
总结,配置Data Source是J2EE应用程序部署的关键步骤,尤其是在Websphere和Tomcat这样的服务器环境中。正确配置Data Source可以确保应用程序能够无缝地与各种数据库进行交互,从而实现高效的数据存取和管理。在实践...
在IBM WebSphere Application Server (WAS) 7.0中配置MySQL数据源是一个关键步骤,它允许应用程序通过JDBC(Java Database Connectivity)与MySQL数据库进行交互。以下是详细的配置过程: **一、配置 J2C 认证别名*...
在WebSphere Application Server中,JAR(Java Archive)文件是一种包含Java类文件、资源文件和其他元数据的标准打包格式,主要用于模块化地组织和分发Java代码。这些JAR文件对于WebSphere的正常运行至关重要,它们...
确保CXF相关的JAR文件不与WebSphere自带的JAR文件冲突,避免在类路径中重复包含相同库。可以通过WebSphere的管理控制台调整类加载顺序,例如设置“parent last”策略,让WebSphere优先使用应用的类。 2. **...
标题中的“WebSphere数据源配置”是指在IBM的WebSphere应用服务器中设置和管理数据库连接的过程。WebSphere作为一款强大的企业级应用服务器,提供了一种高效且灵活的方式来配置数据源,以便应用程序能够与各种数据库...
根据提供的信息来看,用户在部署了一个WebSphere集群后,发现通过WebService接口传递的数据中,所有的中文字符都显示为问号,同时在日志文件中也出现了乱码的情况。这一现象表明系统在处理中文字符时存在问题。 **...
7. **JDBC连接问题**:WebSphere 6.1中配置Oracle数据源时,用户和密码不应直接在数据源属性中设置,而应使用J2C认证方式。这可以解决认证失败的错误。 8. **80端口使用**:若需要在WebSphere上使用80端口,需要在...
【标题】:“与 WebSphere Integration Developer 适配器连接,第 3 部分” ...因此,对于那些希望在WebSphere环境中整合多种数据源的开发团队来说,理解和熟练使用WebSphere Adapter for JDBC是至关重要的。
通过对线程状态的检查,可以定位到导致死锁的特定代码,然后通过调整锁的顺序、超时机制或使用更高级的并发控制策略来避免死锁。 再者,垃圾回收(Garbage Collection, GC)是Java虚拟机管理内存的重要机制。不合理...
在入门教程中,你将学习到如何设置和使用MQ进行可靠的消息传递,理解其工作原理,包括队列、通道、消息格式等概念,以及如何在分布式环境中实现数据通信。 【知识点四】:Websphere的部署与管理 理解如何在...