开始怀疑Spring框架的jdbc事务处理方式

lemon_zc1949 2005-09-28 10:40:58
目前我做了个小小的试验,证明了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条记录.

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






...全文
595 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
myth822 2005-09-28
  • 打赏
  • 举报
回复
<property name="target" ref="accountservice_target" />

accountservice_target换成具体的bean试一下
sgdb 2005-09-28
  • 打赏
  • 举报
回复
你mysql的版本呢,有可能是你的mysql不支持回滚
blueoxygen 2005-09-28
  • 打赏
  • 举报
回复
http://www.javaeye.com/viewtopic.php?t=11190&highlight=%CA%C2%CE%F1
这个应该对你有用
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
doRollback() 是 DataSourceTransactionManager的一个方法。
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
我跟踪了代码的,抛出异常后Spring的事务处理开始活动了。它调用了:org.springframework.jdbc.datasource.DataSourceTransactionManager的回滚方法,并且我也查到了使用的connection,connection的AutoCommit确实是false哦。

protected void doRollback(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
}
try {
con.rollback();
}
catch (SQLException ex) {
throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
}
}

上面的 doRollback() 确实是调用了的。
并且也调用了: con.rollback() 的。
blueoxygen 2005-09-28
  • 打赏
  • 举报
回复
to 楼上
这个事务处理可以container mainten的阿,为什么都要手写呢?
mituzhishi 2005-09-28
  • 打赏
  • 举报
回复
事务是要你个人手工搞定的吧?

你又没写回滚的代码,它为什么要回滚?
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
我回到了my sql 下。我把mysql的table类型从MyISAM改为InnoDB就可以了。但还没有试验过其它类型。
hlnccc 2005-09-28
  • 打赏
  • 举报
回复
又来晚了??
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
非常感谢大家。
very thanks
springInJava 2005-09-28
  • 打赏
  • 举报
回复
spring的事务管理是基于method级,举个例子
一个业务bean里面有两个方法method1,method2
method1里面有insert1,udpate1两个操作
method2里面有insert2,update2两个操作
如果在method2里面的update2发生异常的话,method1里面的操作是不会回滚的。
只会回滚method2里面的两个操作,就是insert2,update2两个操作回滚
mxlmwl 2005-09-28
  • 打赏
  • 举报
回复
呵呵,刚刚用google查了一下“mysql 事务处理”,你看一下,对你会有帮助的。
mxlmwl 2005-09-28
  • 打赏
  • 举报
回复
呵呵,来晚了一步。sgdb(神天月晓) ( ) 的说法是对的,记得以前说mysql好象是不支持事务处理的,不过新版本(好象是3.x,具体是哪个之后就记不清了)是支持的,但是需要改下设置,然后重新编译才可以使用,默认安装的是不支持事务的。

oracle当然支持,地球人都知道。
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
谢谢 sgdb(神天月晓) :确实是MySQL设置的问题,我换用oracle就正确了。我等下去看下如何设置mysql的事务。我一直怀疑自己的代码,没有怀疑数据库自身,确实有点愚昧。
sgdb 2005-09-28
  • 打赏
  • 举报
回复
你还是应该去测试一下,看看你的table是否支持事务,mysql的事务是比较奇怪的,
如果你的表是非事务表,rollback是不起作用的。具体去查查mysql的手册。
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
Spring的事务有2种方式:
1。编程的方式,使用TransactionTemplate
2。AOP方式,基本就是我的这种配置方式
lemon_zc1949 2005-09-28
  • 打赏
  • 举报
回复
刚才我使用了hibernate也不行。郁闷中。
我mysql的版本是:4.1.11 for windows的。


枫红一刀:你的意思我没懂哈。具体bean是什么?
第1章:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识。   第2章:通过一个简单的例子展现开发Spring Web应用的整体过程,通过这个实例,读者可以快速跨入Spring Web应用的世界。   第3章:讲解Spring IoC容器的知识,通过具体的实例详细地讲解IoC概念。同时,对Spring框架的三个最重要的框架级接口进行了剖析,并对Bean的生命周期进行讲解。   第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。   第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们还将对Spring容器一些高级主题进行深入的阐述。   第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。   第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、使用注解进行配置等内容。   第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等内容。   第9章:介绍了Spring事务管理的工作机制,通过XML、注解等方式进行事务管理配置,同时还讲解了JTA事务配置知识。   第10章:对实际应用中Spring事务管理各种疑难问题进行透彻的剖析,让读者对Spring事务管理不再有云遮雾罩的感觉。   第11章:讲解了如何使用Spring JDBC进行数据访问操作,我们还重点讲述了LOB字段处理、主键产生和获取等难点知识。   第12章:讲解了如何在Spring中集成Hibernate、myBatis等数据访问框架,同时,读者还将学习到ORM框架的混用和DAO层设计的知识。   第13章:本章重点对在Spring中如何使用Quartz进行任务调度进行了讲解,同时还涉及了使用JDK Timer和JDK 5.0执行器的知识。   第14章:介绍Spring 3.0新增的OXM模块,同时对XML技术进行了整体的了解。   第15章:对Spring MVC框架进行详细介绍,对REST风格编程方式进行重点讲解,同时还对Spring 3.0的校验和格式化框架如果和Spring MVC整合进行讲解。   第16章:有别于一般书籍的单元测试内容,本书以当前最具实战的JUnit4+Unitils+ Mockito复合测试框架对如何测试数据库、Web的应用进行了深入的讲解。   第17章:以一个实际的项目为蓝本,带领读者从项目需求分析、项目设计、代码开发、单元测试直到应用部署经历整个实际项目的整体开发过程。

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧