配置spring注入事务处理,出错,help....
--------------------编程问答-------------------- 你的事务管理切入点如果在dao层,回滚的就是一条数据,如果在service层,回滚的就是这次操作里面所有的数据。
至于你其他的问题,没怎么理解,可以回帖继续问下。 --------------------编程问答-------------------- http://download.csdn.net/detail/lsdbestboy/4909948希望这个可以帮到你 --------------------编程问答--------------------
你指的切入点,是指@Transactional(rollbackFor=Exception.class)命令么 ?
我就是想问,我有一个类,里面有个insert方法,在方法里我new了一个dao类,面有两个插入方法,分别插入两个表,在这个方法里,我想让第二哥插入语句出错的时候,第一条插入失败,数据回滚,为啥不行 ?
public class TransactionTestService{
private DataMoniterDao dataMoniterDao;
@Transactional(rollbackFor=Exception.class)
public void insertTest() throws Exception{
try {
// 查询信息
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
dataMoniterDao = (DataMoniterDao) appContext.getBean("DataMoniter");
// 传参用MAP
Map<String,String> map = new HashMap<String, String>();
map.put("pNewRank", "ss");
map.put("sDate", "2012-12-20");
dataMoniterDao.insertIRankData(map);
dataMoniterDao.insertTestData("1");
// this.getSqlMapClientTemplate().insert("DataMoniter.insertIRankData",map);
// this.getSqlMapClientTemplate().insert("DataMoniter.insertTestData","1");
} catch (Exception e) {
throw e;
}
}
}
--------------------编程问答-------------------- try catch去掉试试 --------------------编程问答-------------------- 不好用
我调用insert方法的类,就是一个普通类,不实现任何接口,有关系么 ? --------------------编程问答-------------------- 没看到配置文件中定义事务的切入点,是不是你的DAO没定义事务控制。 --------------------编程问答--------------------
怎么配置的 ?发个代码来呗,谢谢! --------------------编程问答--------------------
发一篇博文,希望能有用
http://artjsk.blog.163.com/blog/static/185055362201292681914865/ --------------------编程问答--------------------
除了不要catch(可以throw,在上层捕获),你insert方法所在类,就是DAO,有没有被Spring容器识别(比如通过@Repository) --------------------编程问答--------------------
没加@Repository,但是有什么影响呢 ?我改了之后还是同样的效果...
service层的代码,还是第一条可以正常插入,事务处理不起作用
@Service
public class DataMoniterServiceImpl implements IDataMoniterService{
private DataMoniterDao dataMoniterDao;
@Override
@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
public void save(RequestParamDto paramDto) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
dataMoniterDao = (DataMoniterDao) appContext.getBean("dataMoniterDao");
// TODO Auto-generated method stub
Map<String,String> map = new HashMap<String, String>();
map.put("pNewRank", "ss");
map.put("sDate", "2012-12-20");
dataMoniterDao.insertIRankData(map);
dataMoniterDao.insertTestData("1");
}
}
dao层的代码
@Repository(value = "dataMoniterDao")
public class DataMoniterDao extends SqlMapClientDaoSupport implements IDataMoniterDao{
// 事务处理直接写在dao的一个方法里,就好用,分开后放到service层就不行了
@Override
//@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
//@Transactional(rollbackFor=Exception.class)
//@Transactional(propagation=Propagation.REQUIRED)
public void insertIRankData(Map<String, String> map) {
// TODO Auto-generated method stub
this.getSqlMapClientTemplate().insert("DataMoniter.insertIRankData",map);
//this.getSqlMapClientTemplate().insert("DataMoniter.insertTestData","1");
}
public void insertTestData(String test) {
// TODO Auto-generated method stub
this.getSqlMapClientTemplate().insert("DataMoniter.insertTestData",test);
}
}
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<context:component-scan base-package="com.test"/>
<context:annotation-config />
<mvc:annotation-driven />
<!--<aop:aspectj-autoproxy proxy-target-class="true"/>-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView
</value>
</property>
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<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://192.168.100.11/test"/>
<property name="username" value="root"/>
<property name="password" value="spr"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<!-- <value>classpath:sqlMapConfig.xml</value>-->
<value>classpath:sqlMapConfig.xml</value>
</property>
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
<!-- 定义事物处理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.test.rf.service..*.*(..))" id="allMethod"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allMethod"/>
</aop:config>
<!--根据sqlMapClien创建一个SqlMapClient模版类-->
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient">
<ref bean="sqlMapClient" />
</property>
</bean>
<bean id="DataMoniter" class="com.test.rf.dao.DataMoniterDao">
<property name="sqlMapClientTemplate">
<ref bean="sqlMapClientTemplate" />
</property>
</bean>
<bean id="dataMoniterDao" class="com.test.rf.dao.DataMoniterDao">
<property name="sqlMapClientTemplate">
<ref bean="sqlMapClientTemplate" />
</property>
</bean>
</beans>
帮忙看看是不是xml配置的有问题 ? --------------------编程问答--------------------
哥们,我现在也怀疑是配置文件的事务切入点有问题,因为我像下面这么写,在dao中
事务处理是好用的,insertTest如果出错,insertIRankData的数据也插入不了
@Transactional
@Repository(value = "dataMoniterDao")
public class DataMoniterDao extends SqlMapClientDaoSupport implements IDataMoniterDao{
@Override
//@Transactional(readOnly = true, propagation=Propagation.REQUIRED)
@Transactional(rollbackFor=Exception.class)
//@Transactional(propagation=Propagation.REQUIRED)
public void insertIRankData(Map<String, String> map) {
// TODO Auto-generated method stub
this.getSqlMapClientTemplate().insert("DataMoniter.insertIRankData",map);
this.getSqlMapClientTemplate().insert("DataMoniter.insertTestData","1");
}
}
但是我像下面,把两个insert在dao中分成两个方法,在service层调用,则事务完全不起作用,并没有回滚
@Transactional
@Repository(value = "dataMoniterDao")
public class DataMoniterDao extends SqlMapClientDaoSupport implements IDataMoniterDao{
@Override
public void insertIRankData(Map<String, String> map) {
// TODO Auto-generated method stub
this.getSqlMapClientTemplate().insert("DataMoniter.insertIRankData",map);
}
@Override
public void insertTestData(String test) {
// TODO Auto-generated method stub
this.getSqlMapClientTemplate().insert("DataMoniter.insertTestData",test);
}
}
[/code]
根据你给的文章,我反复对过,配置都一样...不知道为什么还是不行,快要崩溃了,被这个问题搞得…… --------------------编程问答-------------------- --------------------编程问答-------------------- 有没有了解的,帮忙指导下,谢谢 --------------------编程问答--------------------
我对这个不是很熟,
不过我觉得可能是不是这样,当你Dao中方法有两条或两条以上执行语句的时候,在Dao上定义Transactional是有意义的,但只有一条语句时,我觉得就失去意义了
这个时候在Service上定义Transactional是有意义的,但这时候你的事务不知道是不是受这个定义限制了
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" read-only="true"/>
</tx:attributes>
</tx:advice>
只有insert开头的方法具有事务?那Service中save方法是不是不受事务控制了 --------------------编程问答--------------------
我把insert改成save了,也不好用,就是在dao中起作用,service层不起作用 --------------------编程问答--------------------
--------------------编程问答--------------------
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.test.rf.service.*.*(..))" id="allMethod"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allMethod"/>
</aop:config>
<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
应该类似这样吧,save方法是readonly的也不对的。
p.s.我上面有个说得不严谨,Transactional应该对两条或两条以上的数据库原子操作才有意义。
--------------------编程问答-------------------- 什么情况,用注解,又用配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
classpath:/org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
classpath:/org/springframework/context/config/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
classpath:/org/springframework/aop/config/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
classpath:/org/springframework/transaction/config/spring-tx-2.5.xsd">
<!-- 配置哪些包下的类需要自动扫描 -->
<context:component-scan base-package="com"/>
<!-- 这里的jun要与persistence.xml中的 <persistence-unit name="jun" transaction-type="RESOURCE_LOCAL">
中的name值要一致,这样才能找到相关的数据库连接
-->
<context:property-placeholder location="/WEB-INF/config/jdbc.properties"/>
<!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" lazy-init ="true"> -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="initialSize" value="${initialSize}"/>
<property name="maxActive" value="${maxActive}"/>
<property name="maxIdle" value="${maxIdle}"/>
<property name="minIdle" value="${minIdle}"/>
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1 FROM DUAL" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceXmlLocation" value="/WEB-INF/config/persistence.xml" />
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
<!--
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="jun"/>
</bean>
-->
<!-- 使用jdbcTemplate的batchUpdate实现批处理 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="jun" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<!-- <property name="hibernate.hbm2ddl.auto" value="update"/>-->
<property name="hibernate.jdbc.fetch_size" value="18"/>
<property name="hibernate.jdbc.batch_size" value="10"/>
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
@Service
@Transactional
public class CredituserServiceimp extends DaoSupport implements CredituserService{
private static Logger logger = Logger.getLogger(CredituserServiceimp.class);
public List getChlid(String userid, String usertype) {
List list = new ArrayList();
String sql = "";
try {
//ts = session.beginTransaction();
if (usertype.equals("Association")) {
sql = "select accountname,company from CUSTOMER t where customertype='1'";
} else if (usertype.equals("Customer")) {
sql = "select accountno,company from AGENCY t where substr(accountno,0,length(accountno)-"
+ 3 + ")='" + userid + "'";
} else {
sql = "select accountno as userid,company as name from AGENCY t where substr(accountno,0,length(accountno)-"
+ 3
+ ")='"
+ userid
+ "'"
+ " union all select saleperson as userid,name as name from SALEUSERS where substr(saleperson,0,length(saleperson)-"
+ 4 + ")='" + userid + "'";
}
list =this.Exec(sql);
} catch (Exception e) {
e.printStackTrace();
logger.error(e);
}
return list;
} --------------------编程问答--------------------
关键是注释和配置都不好用... --------------------编程问答-------------------- 肯定还是你serivce层的事物切入点的问题,能看看你service层的调用代码吗???我想问题就出在这里了。。。 --------------------编程问答--------------------
是调用service的代码,还是service本身的代码 ?
--------------------编程问答-------------------- 配置下事务的传播属性就行了。 --------------------编程问答--------------------
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
@Service
public class DataMoniterServiceImpl implements IDataMoniterService{
private DataMoniterDao dataMoniterDao;
private IRankDao iRankDao ;
private RDateDao rDateDao ;
private ColorConfigureDao colorConfigureDao ;
/**
* 变更滞留时间和身份等级数据
*/
@Override
@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRED)
public Map<String, String> save(RequestParamDto paramDto,Map<String,String> paramMap){
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
iRankDao = (IRankDao) appContext.getBean("iRankDao");
rDateDao = (RDateDao) appContext.getBean("rDateDao");
// TODO Auto-generated method stub
Map<String,String> map = new HashMap<String, String>();
Map<String,String> model = new HashMap<String, String>();
// 更新时间
Date dt = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String sDate = sdf.format(dt);
// 拼接滞留时间数据
String newRDate = paramDto.getStartRDate() + "日至" + paramDto.getEndRDate() + "日";
// 更新数据
map.put("iRank", paramDto.getINewRank());
map.put("sDate", sDate);
map.put("rDate", newRDate);
// 身份等级更新
if (!"".equals(paramDto.getINewRank())) {
iRankDao.save(map);
}
// 滞留时间更新
if (!"".equals(paramDto.getStartRDate()) && !"".equals(paramDto.getEndRDate())) {
rDateDao.save(map);
}
// 处理成功消息返回画面
model.put("Success", Const.I_SUCCESS_MSG);
model.put("Error", Const.ERROR_EMPTY);
return null;
}
}
求助,怎么配置 ?
补充:Java , Web 开发