JiveJdon Community Forums
在线441人   首页   主题表   培训咨询   标签   精华   查搜   注册    登陆 RSS
首页 » 论坛 » 开源项目大家谈
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表
???en_US.forumThreadNext.name??? 下一主题
Go 总共有 7 回复 / 1
 发表新帖子   回复该主题贴
lemon_zc1949

悄悄话
发表文章: 2
注册时间: 2005年09月28日 15:08
开始怀疑Spring框架的jdbc事务处理方式 2005年09月28日 15:13 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
标签列表 spring(39)      事务(70)     
目前我做了个小小的试验,证明了Spring的jdbc事务的问题。我的环境:
使用jakarta commons dbcp 的 org.apache.commons.dbcp.BasicDataSource,作为DataSource.
xml中的配置如下:

<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name=
"driverClassName" value="com.mysql.jdbc.Driver" />
<property name=
"url" value="jdbc:mysql://localhost/TransactionTest" />
<property name=
"username" value="zc" />
<property name=
"password" value="zc" />
<property name=
"defaultAutoCommit" value="false" />
</bean>


my sql 数据库TransactionTest中有2个表,一个account, 一个accountprofile,分别弄了2个dao

<bean id=
"accountdao"
class=
"test.AccountDaoImp" >
<property name=
"dataSource" ref="datasource" />
</bean>

<bean id=
"accountprofiledao"
class=
"test.AccountProfileDaoImp" >
<property name=
"dataSource" ref="datasource" />
</bean>



事务管理器配置:

<bean id=
"dbTransactionManager"
class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name=
"dataSource" ref="datasource" />
</bean>


业务门面:

<bean id=
"accountservice_target"
class=
"test.AccountService" >
<property name=
"accountDao" ref="accountdao" />
<property name=
"accountProfileDao" ref="accountprofiledao" />
</bean>



最后配置Spring的事务代理(其实就是利用了AOP):

<bean id=
"accountservice" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
<property name=
"transactionManager" ref="dbTransactionManager" />
<property name=
"target" ref="accountservice_target" />
<property name=
"transactionAttributes" >
<props>
<prop key=
"register*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>



我的业务门面实现有个方法:

public void registerAccount(Account a, AccountProfile ap){
accountDao.insert(a);
accountProfileDao.insert(ap);
}


分别调用2个dao的insert()方法,Account, AccountProfile是值对象。

测试代码:

public static void main(String[] args) {
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(
"beans.xml");

AccountService service = (AccountService) context.getBean(
"accountservice");

Account a = new Account();
a.setId(
"U001");
a.setName(
"zc");
a.setPhone(
"123");

AccountProfile ap = new AccountProfile();
ap.setName(a.getName());
// "zc"
ap.setPassword(
"abcdef");

service.registerAccount(a,ap);

a = new Account();
a.setId(
"U002");
a.setName(
"zc");
a.setPhone(
"123");

ap = new AccountProfile();
ap.setName(a.getName());
// "zc"
ap.setPassword(
"12345");

service.registerAccount(a,ap);

context.close();

}



由于表accountprofile 的name 字段是唯一的,所以第2次registerAccount()要出现异常。

也就是在第2次执行registerAccount()时

{
accountDao.insert(a);
accountProfileDao.insert(ap);
// 这要抛出异常
}



但前面的 accountDao.insert(a) 无法回滚呢?

数据库结果:account有2条记录,id不同,但name相同, accountprofile有1条记录.

数据库不一致, 事务没起到作用。




lemon_zc1949

悄悄话
发表文章: 2
注册时间: 2005年09月28日 15:08
Re: 开始怀疑Spring框架的jdbc事务处理方式 2005年09月28日 15:18 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
Spring的事务有2种方式:
1。编程的方式,使用TransactionTemplate的execute方法。
2。AOP方式,通过配置来启动事务。

我上面的方法是采用AOP方式。

还有,我试验做过,如果使用相同的DataSource,调用它的getConnection(),那么获取的Connection(连接池封装了的)的hashCode都不一样,也就是说Connection是不一样。注射给 2个dao以及TransactionManager的DataSource是同意个DataSource(单列),单他们在使用DataSource的时候可能使用的Connection是不同的,所以无法实现事务混滚, 不知道是不是这样?

有点郁闷。
banq

悄悄话
发表文章: 9528
注册时间: 2002年08月03日 17:08
Re: 开始怀疑Spring框架的jdbc事务处理方式 2005年09月28日 21:29 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
如果你不是MySQL 5.0,你需要指定Mysql的事务机制是INNO DB。

你在JBoss下试验看看。
banq

悄悄话
发表文章: 9528
注册时间: 2002年08月03日 17:08
Re: 开始怀疑Spring框架的jdbc事务处理方式 2005年09月29日 10:45 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
Spring只提供使用JTA JMS等方便使用方式,但是不提供这些服务,必须由容器提供,你需要使用JBoss.
浆糊

悄悄话
发表文章: 244
注册时间: 2002年08月06日 19:20
Re: 开始怀疑Spring框架的jdbc事务处理方式 2005年09月29日 13:25 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
拜托先确保数据库的事务能力好伐?
0000ps

悄悄话
发表文章: 2
注册时间: 2008年01月29日 18:08
re:开始怀疑Spring框架的jdbc事务处理方式 2008年01月29日 18:12 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
我也做了个类似的例子, 只用jdbc 和 Spring , 没有用Hibernate和任何应用服务器....
结果也是控制不了transaction, 不过从log4j的输出看,
的确该rollback的exception是有rollback, 该commit的exception也是有commit. 貌似Spring rollback和commit的connection 和我用来做DB操作的connection是两个实例 .... ()

[org.springframework.transaction.interceptor.TransactionInterceptor] - Completing transaction for <b>[dream.service.JdbcService.insertTTRange] after exception: dream.exception.ToRollbackException
[org.springframework.transaction.interceptor.RuleBasedTransactionAttribute] - Applying rules to determine whether transaction should rollback on dream.exception.ToRollbackException
[org.springframework.transaction.interceptor.RuleBasedTransactionAttribute] - Winning rollback rule is: RollbackRuleAttribute with pattern [ToRollbackException]
[org.springframework.jdbc.datasource.DataSourceTransactionManager] - Triggering beforeCompletion synchronization
[org.springframework.jdbc.datasource.DataSourceTransactionManager] - Initiating transaction rollback
[org.springframework.jdbc.datasource.DataSourceTransactionManager] - Rolling back JDBC transaction on Connection </b>[jdbc:microsoft:sqlserver://AspenServer:1433;NETADDRESS=000000000000;HOSTPROCESS=0;SENDSTRINGPARAMETERSASUNICODE=true;LOGINTIMEOUT=0;DATABASENAME=Test;PROGRAMNAME=;SELECTMETHOD=direct;WSID=, UserName=sa, SQLServer]
[org.springframework.jdbc.datasource.DataSourceTransactionManager] - Triggering afterCompletion synchronization
[org.springframework.transaction.support.TransactionSynchronizationManager] - Clearing transaction synchronization
[org.springframework.transaction.support.TransactionSynchronizationManager] - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1dacccc] for key [org.apache.commons.dbcp.BasicDataSource@e41bc3] from thread [main]
[org.springframework.jdbc.datasource.DataSourceTransactionManager] - Releasing JDBC Connection [jdbc:microsoft:sqlserver://AspenServer:1433;NETADDRESS=000000000000;HOSTPROCESS=0;SENDSTRINGPARAMETERSASUNICODE=true;LOGINTIMEOUT=0;DATABASENAME=Test;PROGRAMNAME=;SELECTMETHOD=direct;WSID=, UserName=sa, SQLServer] after transaction
[org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource

[该贴被0000ps于2008-01-29 18:13修改过]
banq

悄悄话
发表文章: 9528
注册时间: 2002年08月03日 17:08
回复:re:开始怀疑Spring框架的jdbc事务处理方式 2008年01月30日 16:57 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
Spring引入显式事务表面上给使用者带来可配置方便,太实际上引入了复杂性,Spring+Hibernate必须强制配置事务,否则无法运行,这些从一个侧面看事务和线程一样不是那么好驾驭的,这也是EJB将事务封装到容器一个原因之一,Spring打破这个盒子,曾经被一些盲目跟从者叫好,同时他们必须面对潘多拉盒子打开的后果。

现在Grails又试图将Spring+Hibernate及其它打开的潘多拉盒子冒出的魔鬼一起再封装到一个新的盒子里..

唉,,分久必和 合久必分。螺旋式上升?
[该贴被banq于2008-01-30 17:14修改过]
0000ps

悄悄话
发表文章: 2
注册时间: 2008年01月29日 18:08
回复:re:开始怀疑Spring框架的jdbc事务处理方式 2008年01月31日 15:34 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
sorry, 我收回我说的..
spring在纯jdbc也可以控制事务,
不过dataSource要以注入的方式获取..

不然Spring最后commit 或rollback的connection, 和数据操作的connection是不同的object, 这样就会造成Spring没有在控制transaction的假象
这个主题有 7 回复 / 1Go
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表    返回页首返回页首
???en_US.forumThreadNext.name??? 下一主题
热点TAG: AOP cache 缓存 DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Seam Spring Struts
正在读取,请等待...
google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘 博采网摘
查询本论坛内 回复超过的热门帖子
     回复该主题贴
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
  每2分种自动备份发贴内容Ctrl-V粘贴取出,提问题前先查询标签列表

RSS 手机阅读 add to google add to yahoo
解惑之道在J道 ,打造中国最具影响力的的企业软件社区
OpenSource JIVEJDON v3.0 Powered by JdonFramework Code © 2002-08 jdon.com

anti spam