关于插入主键立刻返回主键值的知识,不能用存储过程。
目前如下:
调用的插入配置:单独调用一点问题没有。
<insert id="BatchAddForZh" parameterClass="ParamContext">
<![CDATA[
insert into t_salary (
AREA_ID, ORG_ID, USER_ID)
SELECT
A.AREA_ID as AREA_ID, A.ORG_ID as ORG_ID, USER_ID
from t_salary A
inner join t_acl_for_salary B on(A.AREA_ID=B.AREA_ID and A.ORG_ID=B.ORG_ID)
inner join t_workstate C on(B.ACC_ID=C.ACC_ID and C.RYLB_FLAG ='1')
]]>
<selectKey resultClass="java.lang.Integer" type="post" keyProperty="pkId">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
方法
@Transactional
public void batchAddSForZhFlow(ParamContext param){
saveWorkStateForZh(param);
int retVal=batchAddSalaryForZh(param);//这个调用以上的insert,这个没调用成功返回的就不是0了,返回saveWorkStateForZh执行后的主键值,数据库配置为可重复读。这样还是不行。
System.out.println(retVal);
if(retVal>0){
saveOrUpdateWorkStateForZh(param);
}
}
@Transactional(propagation = Propagation.NESTED)
public void saveWorkStateForZh(ParamContext param) {
也是一个插入操作
}
@Transactional(propagation = Propagation.NESTED)
public void saveOrUpdateWorkStateForZh(ParamContext param) {
也是一个插入操作
}
@Transactional(propagation = Propagation.NESTED)
public void batchAddSalaryForZh(ParamContext param) {
也是一个插入操作
}
问题出来了,saveWorkStateForZh插入的返回值为15,而batchAddSalaryForZh没有插入成功,那么返回可不是0哦,是15,因为这个方法使用的是一个DB连接,
有人说要用jta,我就更郁闷了,jta可不是所有容器都支持的,也就一些重量级容器有这样的服务。
目前把如下代码写入action中虽然可以用,但是也没有百分百优秀。
saveWorkStateForZh(param);
int retVal=batchAddSalaryForZh(param);
if(retVal>0){
saveOrUpdateWorkStateForZh(param);//如果这里出现错误,是应该回滚上一个操作,但是事物控制没有在action这一区间,虽然也很少出错,但是网络阻塞超过连接配置时间回滚也不一定完整。
}
也有如下的解决方案:
@Transactional
public void batchAddSForZhFlow(ParamContext param){
saveWorkStateForZh(param); //将此操作分离出来,但是这个方法的确和如下方法是一个原子事务操作。分离又有别的问题衍生。
int retVal=batchAddSalaryForZh(param);
if(retVal>0){
saveOrUpdateWorkStateForZh(param);
}
}
还有些朋友说,干脆合并成一个表,效率更高。。。。。
操作的是两个表,但是这两个表要保持数据一致对应。谁有类似经历可以多说说!也可看看如下人的观点:
http://topic.csdn.net/u/20100402/17/fffb62aa-a73b-49c8-b916-a1713d991777.html