Spring事务管理失效!如何解决?

happyking999 2011-12-05 02:56:23

<!--为业务逻辑Bean配置事务代理 -->
<bean id="testTrans" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="test"/>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

在业务逻辑Bean的方法中有一个insert方法,其中会分别保存两行数据,第一行数据是能成功保存的,第二行数据在程序执行中是会包异常的,由于有Spring 的事务管理,这个时候应该会执行事务回滚,但是实际上我的第一行数据还是被保存了!说明事务管理失效了,这该如何解决了???
...全文
384 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
比丘 2011-12-07
  • 打赏
  • 举报
回复
<prop key="insert*">PROPAGATION_REQUIRED</prop>你加上异常类型看看
<prop key="add*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>这好像这样
happyking999 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 graduate2011 的回复:]
我以前也遇到过类似的,结果发现是mysql的问题。不知道你用的是数据库是不是mysql,因为默认表类型是MyISAM不支持事务管理的,要改为InnoDB才行。
[/Quote]
我的MySQL表类型是InnoDB的
lxbccsu 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用楼主 happyking999 的回复:]
XML code


<!--为业务逻辑Bean配置事务代理 -->
<bean id="testTrans" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="trans……
[/Quote]
楼主说了业务逻辑Bean的方法中有一个insert方法,会分别保存两行数据;
不知道业务逻辑Bean是Service层中的bean还是个DAO?
Spring的事务应该配置在Service的bean中;

示例:
TestServiceImpl{
TestDao testDao;
public void insert(){
testDao.save();//success
testDao.save();//fail
}
}

最后是上面说的异常和数据库问题,需要一一排除;
easonwang14 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 q358417681 的回复:]

XML code
<bean id="superDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="tranMager"/>
1……
[/Quote]

我xml的配置也是你这样的配的!~~麻烦你把java代码也贴出来 下吧...谢谢
it-er 2011-12-06
  • 打赏
  • 举报
回复
我以前也遇到过类似的,结果发现是mysql的问题。不知道你用的是数据库是不是mysql,因为默认表类型是MyISAM不支持事务管理的,要改为InnoDB才行。
比丘 2011-12-06
  • 打赏
  • 举报
回复
<bean id="superDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="tranMager"/>
1.2事务管理规则
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="update*">PROPAGATION_REQUIRED,-java.lang.Exception</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>

这是我的事务你看看吧,我这个事务大概的意思是,管理以add开头,update开头的方法,-java.lang.Exception为管理事务的异常类型,其他方法都为只读方法

<bean id="bookBizPro" parent="superDao">
<property name="target" ref="bookBiz"></property>
</bean>

这是事务管理的业务类
当你注入到action中的话只能用bookBizPro,如果你用bookBiz是没有事务管理的
laiyu_ryan 2011-12-06
  • 打赏
  • 举报
回复
service层的异常往外抛,在action层捕获异常,service层调用的dao层的代码就会回滚了
happyking999 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 easonwang14 的回复:]
额..不好意思..才看到..
这个问题有消息了..麻烦通知我一下...相当感谢
[/Quote]
嗯 会的 不过目前还没解决
happyking999 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 easonwang14 的回复:]
我用的是Oracle~~~~~~~~~
[/Quote]
那我就不知道了。。。
easonwang14 2011-12-06
  • 打赏
  • 举报
回复
我用的是Oracle~~~~~~~~~
happyking999 2011-12-06
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 easonwang14 的回复:]
哎~!~~~
我们两个苦逼呐!!~~~
[/Quote]
我发现很有可能还是MySQL的问题,表的类型如果为MyISAM的话是不支持事务管理的,你看你的表类型是不是这个。
我的MySQL版本是5.1.X(好像不支持InnoDB表类型) 虽然MySQL中的my.ini文件中default-storage-engine=INNODB
但是建表时默认的还是MyISAM,改成INNODB就会报错。我现在在考虑这个问题了。你可以修改以下表类型试试。
lxbccsu 2011-12-06
  • 打赏
  • 举报
回复
只一个疑问:
JdbcTemplate jt = new JdbcTemplate(ds);
是不是Spring受管的对象?
easonwang14 2011-12-06
  • 打赏
  • 举报
回复
哎~!~~~
我们两个苦逼呐!!~~~
happyking999 2011-12-06
  • 打赏
  • 举报
回复
数据库名:test
表名:mytable
表中就一个字段:id (int型 primary key)
happyking999 2011-12-06
  • 打赏
  • 举报
回复
我实在是找不到问题出在哪了!!!我把我所有的代码贴上来吧,望高人解决啊!
bean.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!--定義數據源Bean,使用C3P0數據源實現-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost/test"/>
<property name="user" value="root"/>
<property name="password" value="1234"/>
<property name="maxPoolSize" value="40"/>
<property name="minPoolSize" value="1"/>
<property name="initialPoolSize" value="1"/>
<property name="maxIdleTime" value="20"/>
</bean>
<!--配置JDBC數據源的局部事務管理器,使用DataSourceTrannsactionManager類 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>


<bean id="test" class="spring.TestImpl">
<property name="ds" ref="dataSource"/>
</bean>

<!--配置一个业务逻辑组件 -->
<bean id="myService" class="spring.MyServiceImpl">
<!--将DAO组件注入给业务逻辑组件-->
<property name="test" ref="test"/>
</bean>

<!--為業務邏輯Bean配置事務代理 -->
<bean id="testTrans" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<property name="target" ref="myService"/>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>


TestImpl.java实现了Test这个接口(这是DAO),里面就一个insert方法,

package spring;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

public class TestImpl implements Test {

private DataSource ds;

public void setDs(DataSource ds) {
this.ds = ds;
}
public void insert(int i) {
// TODO Auto-generated method stub
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("insert into mytable value("+i+")");
}
}


MyServiceImpl.java是业务逻辑类,实现了MyService接口,注入了Test(DAO)

package spring;

public class MyServiceImpl implements MyService{

private Test test;
public void setTest(Test test) {
this.test = test;
}
@Override
public void insert(int id) {
// TODO Auto-generated method stub
test.insert(id);
test.insert(id);
}
}



MainTest.java是一个测试类

package spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {
public static void main(String arg[])throws Exception {
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
MyService t = (MyService)ctx.getBean("testTrans");
t.insert(1);
}
}



运行后出报异常,我不关心这个异常,我只希望数据库中应该是没有数据的,可事实是insert成功了一个。
easonwang14 2011-12-05
  • 打赏
  • 举报
回复
额..不好意思..才看到..
这个问题有消息了..麻烦通知我一下...相当感谢
happyking999 2011-12-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 easonwang14 的回复:]
我++
哥啊.....我现在跟你一样事务不启效果啊!!!
我想问一下..都把异常抛到service层来了..还不catch掉的话..那怎么办???还往上抛?
[/Quote]
我看过你的帖子,还回复了的。。。
happyking999 2011-12-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 easonwang14 的回复:]
我++
哥啊.....我现在跟你一样事务不启效果啊!!!
我想问一下..都把异常抛到service层来了..还不catch掉的话..那怎么办???还往上抛?
[/Quote]
哥。。。
我也不知道啊!
easonwang14 2011-12-05
  • 打赏
  • 举报
回复
我++
哥啊.....我现在跟你一样事务不启效果啊!!!
我想问一下..都把异常抛到service层来了..还不catch掉的话..那怎么办???还往上抛?
happyking999 2011-12-05
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 huangxw000 的回复:]
Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked

如果遇到checked意外就不回滚。

如何改变默认规则:

1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

2 让unchecked例外不回滚: @Transact……
[/Quote]
从别处copy过来的东西,连改都懒得改下,你怎么好意思发过来?
加载更多回复(4)

67,512

社区成员

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

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