spring配置如下:
<bean id= "proxoolDataSource " class= "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name= "driverClassName">
<value>org.logicalcobwebs.proxool.ProxoolDriver</value>
</property>
<property name="url">
<value>proxool.insuranceAgentPool</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" >
<ref bean="proxoolDataSource" />
</property>
</bean>
<bean id="businessProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property> <property name="target">
<ref bean="userService" />
</property>
<property name="transactionAttributes">
<props>
<!--这个地方不管我怎么配置,当操作数据库时,事务总是被提交 -->
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>dao 的配置
<bean id="userDao" class="insurance.agent.dao.impl.UserDaoImpl">
<property name="dataSource">
<ref bean="proxoolDataSource"></ref>
</property>
</bean>java dao类:
public class UserDaoImpl extends JdbcDaoSupport implements IUserDao {
public static final String CREATE_USER = "INSERT INTO t_user (USERNAME, PASSWORD) VALUES (?, ?)";
public void addUser(final User user) throws Exception{
public void addUser(final User user) throws Exception{
getJdbcTemplate().update(CREATE_USER,
new PreparedStatementSetter() {
public void setValues(PreparedStatement ps)
throws SQLException {
ps.setString(1, user.getUserName());
ps.setString(2, user.getPassword());
}
}
);
}
}service类中方法。(注意配置时是对add*的方法才自动开启事务的,但是该方法调用后,数据竟然可以save)
public void registerUser(User user) throws Exception{
userDao.addUser(user);
userDao.addUserLog();
}
求高手解答。谢谢。
<bean id= "proxoolDataSource " class= "org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name= "driverClassName">
<value>org.logicalcobwebs.proxool.ProxoolDriver</value>
</property>
<property name="url">
<value>proxool.insuranceAgentPool</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" >
<ref bean="proxoolDataSource" />
</property>
</bean>
<bean id="businessProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property> <property name="target">
<ref bean="userService" />
</property>
<property name="transactionAttributes">
<props>
<!--这个地方不管我怎么配置,当操作数据库时,事务总是被提交 -->
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>dao 的配置
<bean id="userDao" class="insurance.agent.dao.impl.UserDaoImpl">
<property name="dataSource">
<ref bean="proxoolDataSource"></ref>
</property>
</bean>java dao类:
public class UserDaoImpl extends JdbcDaoSupport implements IUserDao {
public static final String CREATE_USER = "INSERT INTO t_user (USERNAME, PASSWORD) VALUES (?, ?)";
public void addUser(final User user) throws Exception{
public void addUser(final User user) throws Exception{
getJdbcTemplate().update(CREATE_USER,
new PreparedStatementSetter() {
public void setValues(PreparedStatement ps)
throws SQLException {
ps.setString(1, user.getUserName());
ps.setString(2, user.getPassword());
}
}
);
}
}service类中方法。(注意配置时是对add*的方法才自动开启事务的,但是该方法调用后,数据竟然可以save)
public void registerUser(User user) throws Exception{
userDao.addUser(user);
userDao.addUserLog();
}
求高手解答。谢谢。
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
使用拦截器也会提交事务。
我的本意是把事务设置在service层,并且只有add开头的才开启事务。
其他不以add开头的service方法,不开启事务,不自动提交。
第一步:配置数据源:实现类和数据库
第二步:配置事务管理器:实现类和使用的数据源。
第三步:配置事务拦截器,指定事务拦截的传播属性
第四步:指定哪些类,包使用什么粒度的拦截。
--------------------------------------------------------------------------
Spring的事务配置,有很多种,不过前面两步基本一致,
第一步:配置数据源:
例如: <!-- 定义数据源 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/db_test7" />
<property name="username" value="root"/>
<property name="password" value="better"/>
</bean>第二步:配置事务管理器:
例如: <!-- 定义事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
下面我将说说Spring几种配置方式第三四步的不同和优缺点:
为指定的一个类的特定方法,指定特定的事务方式:
第三四步合并: <!-- 配置代理定向形式 使用ProxyFactoryBean的子类-->
<bean id="anoProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="transactionManager"/>
<!-- 这里的目标非接口,要导入CGLIB -->
<property name="target" ref="ano">
</property>
<property name="transactionAttributes">
<props>
<!-- 如果没有事务则创建一个事务 -->
<prop key="insert*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!--这是Headsen自己的类-->
<bean id="ano" class="com.TransactionTemplate.AnoJdbcTemplate">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
第一种要一个类一个的配置,第二种可以一下子指定一组有共同事务需求的类:第三步: <!-- 使用通用配置,试用所有类-->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"></property>
<!-- 定义事务的传播属性 -->
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>第四步:
<!-- 定义通用AOP代理 这里也可以使用ProxyFactoryBean,一对一配置-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>AnoJdbc.*</value>
<value>这里可以罗列你要事务拦截的类</value>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>CSDN只允许连续回帖三次。
后面继续,第三种配置方式:
然后我使用第2种方式,还是不行。我写了registerUser的方法,数据还是可以insert进数据库。
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
第三步:配置事务的处理参数 <!-- 本例使用tx,要加入对应的schema才能自动提示 -->
<tx:advice id="jdbcTxAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="del*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" isolation="DEFAULT" timeout="-1" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT" timeout="-1" read-only="true" />
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" timeout="-1" />
</tx:attributes>
</tx:advice>第四步:指定哪些类使用第三步配置的事务 <aop:config proxy-target-class="true">
<!--DAO包下所有类都进行事务代理-->
<aop:pointcut id="pointcut1" expression="execution(* com.*.DAO.*.*(..))" />
<aop:advisor advice-ref="jdbcTxAdvice" pointcut-ref="pointcut1"/>
<!--你还可以指定额外的处理,-->
<!--
<aop:pointcut id="fund" expression="execution(* com.jsjs..*(..))"/>
<aop:aspect ref="springLog">
<aop:before pointcut-ref="fund" method="before"/>
<aop:after-returning pointcut-ref="fund" method="after" returning="retur"/>
<aop:after-throwing pointcut-ref="fund" method="exception" throwing="ex"/>
</aop:aspect>
-->
</aop:config>
上面是第三种方式。
另外看了你问题,老大啊!默认当然是提交的啊!
即便你不设置事务照样提交啊!你的配置一点问题没有啊。事务的配置起不起作用很难看出来的。
例如:
public void registerUser(User user) throws Exception{
userDao.addUser(user);
userDao.addUserLog();
}
先insert到user表,再insert进userLog表,当insert userlog表出错时,回滚事务。
结果发现采用如下这种方式即使userlog出错,也不会回滚user表。
<bean id="businessProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property> <property name="target">
<ref bean="userService" />
</property>
<property name="transactionAttributes">
<props>
<prop key="registerUser*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
刚刚试了一下发现采用TransactionInterceptor的方式可以实现事务回滚。
实在不知道前面一种方式为什么不能实现事务回滚。
2,如果是hibernate和jdbc混用,应选择org.springframework.orm.hibernate3.HibernateTransactionManager类处理事务。
3,不要在有事务的方法中捕获事务定义回滚的异常,否则事务不会回滚。
4,不要将需要事务的类相互注入。
<props>
<prop key="registerUser*">PROPAGATION_REQUIRED</prop>
</props><props>
<!--这个地方不管我怎么配置,当操作数据库时,事务总是被提交 -->
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
靠!看了半天 原理粒度问题!怪不得。白白浪费这么多时间。
add();add();
两个add两个事务。
不是粒度问题,
<props>
<!--这个地方的key已经是 registerUser*了,最初的service方法是以add开头的,所以最初的key是add*-->
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
对了事务我配置是在service层,不是在dao层。
所以 userDao的两个方法不会开启2个事务,只会开启一个事务。如下:
public void registerUser(User user) throws Exception{
//以下2条语句只会开启一个事务。
userDao.addUser(user);
userDao.addUserLog();
}