电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Spring事務管理配置文件問題排查

瀏覽:102日期:2023-09-05 11:38:55

在開發中,遇到了sql語句報錯,但是并沒有回滾的情況。

經過幾天的排查,終于找到了事務沒有回滾的原因。

原來的項目用的是informix的數據庫,原來針對事務回滾的機制都是好用的。我本地用的是mysql數據庫。

先將程序代碼與spring-mybatis.xml配置文件拿過來:

1、程序代碼:

這個問題是在驗證增刪改查返回值時發現的。

兩個操作,刪除時,因為關聯了外鍵,所以會報錯,此時正常情況更新的語句也會回滾,但是并沒有。

/** *@Author: Administrator on 2020/3/12 15:15 *@param: *@return: *@Description:查詢同步情況 */ @Override public PageInfo getSyncstatusPages(Syncstatus vo, int pageNo, int pageSize) { PageHelper.startPage(pageNo, pageSize); /* //查看增刪改查的返回值 //1新增:返回值自己定義,可以是void,int //1-1新增一條數據:插入成功,返回值為1 int insert_success1 = yylfHttpServletMapper.insert('8', '2', '1'); //1-2新增多條數據:插入成功,返回值為插入的數據條數,當有一條數據錯誤時,所有數據都會插入失敗 int insert_success2 = yylfHttpServletMapper.insert_duotiao('7'); String insert_success3 = yylfHttpServletMapper.insert_duotiao_String('7');//不支持返回值為String類型 //1-3新增一條數據:插入失?。褐麈I沖突,會直接報異常 int insert_failed = yylfHttpServletMapper.insert('1', '2', '1'); //1-4插入null:屬性為null,如果表中所有字段允許為null,插入一條所有值均為null的數據 Syncstatus syncstatus1 = null; yylfHttpServletMapper.insertSyncstatus(syncstatus1); //1-5插入一個沒有賦值的對象:屬性為null,如果表中所有字段允許為null,插入一條所有值均為null的數據 Syncstatus syncstatus2 = new Syncstatus(); yylfHttpServletMapper.insertSyncstatus(syncstatus2);*/ /*//2刪除:返回值自己定義,可以是void,int //2-1刪除成功:沒有數據:返回值為0 int delete_success1 = yylfHttpServletMapper.delete('0'); //2-2刪除成功:有多條數據:返回值為刪除的數據條數 int delete_success2 = yylfHttpServletMapper.delete_systemcode('2');*/ //2-3刪除失敗:例如有外鍵:報異常 //3更新:返回值自己定義,可以是void,int //3-1更新成功:沒有數據,返回值為0 //int update_no = yylfHttpServletMapper.update_no('0'); //3-2更新成功:有多條數據,返回更新的數據條數 int update_duotiao = yylfHttpServletMapper.update_duotiao_systemcode('2'); int delete_fail = yylfHttpServletMapper.delete('1'); //3-3更新失敗:例如有外鍵,報異常 //int update_fail = yylfHttpServletMapper.update_fail('1'); //4查詢 //4-1 沒數:String 類型返回null //Object object = yylfHttpServletMapper.select('0'); //4-1 沒數:集合 類型返回[]空集合 //Syncstatus syncstatus3 = new Syncstatus(); //syncstatus3.setStatus('7'); //List<Syncstatus> page0 = yylfHttpServletMapper.getSyncstatusList(syncstatus3); //4-1 沒數:int 類型返回null,如果定義為int會報錯。因為沒數時返回null,可以將返回類型改為String //String i = yylfHttpServletMapper.select_int(0); //4-1:當返回值為對象時,若返回值為空,則返回null //4-2 有數 List<Syncstatus> pages = yylfHttpServletMapper.getSyncstatusList(vo); return new PageInfo<Syncstatus>(pages); }

2、對數據庫的操作:

<update id='update_duotiao_systemcode'> UPDATE aaa SET systemcode = ’3’ WHERE systemcode = #{systemcode,jdbcType=VARCHAR} </update><delete id='delete'> delete from aaa where uuid = #{uuid,jdbcType=VARCHAR} </delete>

3、配置文件:

<?xml version='1.0' encoding='UTF-8'?><beans xmlns='http://www.springframework.org/schema/beans' xmlns:aop='http://www.springframework.org/schema/aop' xmlns:tx='http://www.springframework.org/schema/tx' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:context='http://www.springframework.org/schema/context' xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd'> <bean class='com.p6spy.engine.spy.P6DataSource'> <constructor-arg ref='dataSourceTarget'/> </bean> <!-- 定義使用dbcp2連接池的數據源 此處使用自定義的數據源,將用戶名與密碼解密處理 --> <bean > <property name='url' value='${jdbc.url}'> </property> <property name='username' value='${jdbc.username}'> </property> <property name='password' value='${jdbc.password}'> </property> <property name='driverClassName' value='${jdbc.driverClassName}'> </property> <!-- informix--> <!--<property name='validationQuery' value='select count(*) from systables'> </property>--> <!-- mysql檢測方式 --> <property name='validationQuery' value='select 1'> </property> <!-- oracle檢測方式 <property name='validationQuery' value='select 1 from dual'> </property> --> </bean> <!-- 配置SqlSessionFactoryBean --> <bean class='org.mybatis.spring.SqlSessionFactoryBean'> <!-- 注入數據源 相關信息看源碼 --> <property name='dataSource' ref='dataSource' /> <!-- 掃描的實體所在的包--> <property name='configLocation' value='classpath:mybatis.xml'/> <!-- mapper和resultmap配置路徑 --> <property name='mapperLocations'> <list><value>classpath:mybatis/*Mapper.xml</value> </list> </property> </bean> <!-- 自動掃描mapper接口,注入sqlsessionfactory --> <bean class='org.mybatis.spring.mapper.MapperScannerConfigurer'> <property name='basePackage' value='com.asd.modules.dao'/> </bean> <!-- 啟用類掃描機制,通過元數據配置Service --> <context:component-scan base-package='com.asd'> <context:include-filter type='regex'expression='com.asd.modules.sevice.impl.*ServiceImpl' /> </context:component-scan> <!-- mybatis事物配置 --> <context:annotation-config /> <!-- ================================事務相關控制================================================= --> <bean class='org.springframework.jdbc.datasource.DataSourceTransactionManager'> <property name='dataSource' ref='dataSource' /> </bean> <tx:advice transaction-manager='transactionManager'> <tx:attributes> <tx:method name='delete*' propagation='REQUIRED' read-only='false' rollback-for='java.lang.Exception' no-rollback-for='java.lang.RuntimeException' /> <tx:method name='insert*' propagation='REQUIRED' read-only='false' rollback-for='java.lang.RuntimeException' /> <tx:method name='save*' propagation='REQUIRED' read-only='false' rollback-for='java.lang.RuntimeException' /> <tx:method name='update*' propagation='REQUIRED' read-only='false' rollback-for='java.lang.Exception' /> <tx:method name='find*' propagation='SUPPORTS' /> <tx:method name='get*' propagation='SUPPORTS' /> <tx:method name='select*' propagation='SUPPORTS' /> <tx:method name='*' propagation='REQUIRED' rollback-for='java.lang.Exception' /> </tx:attributes> </tx:advice> <aop:config> <!-- 把事務控制在Service層 --> <aop:pointcut expression='execution(* com.asd.modules.service.impl.*ServiceImpl.*(..))' /> <aop:advisor pointcut-ref='reinsPointCut' advice-ref='reinsAdvice' /> </aop:config></beans>

4、數據庫語句:

-- 創建aaa表用來驗證增刪改查的返回值CREATE TABLE `reserve`.`aaa` ( `uuid` char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `systemcode` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (`uuid`) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- 創建bbb表用來關聯aaa的uuid作外鍵CREATE TABLE `reserve`.`bbb` ( `uuid` char(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `systemcode` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `status` varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (`uuid`) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;alter table bbb add constraint FK_T_POSITI_REFERENCE_T_COMPAN foreign key (uuid)references aaa (uuid);insert into bbb (uuid,systemcode,status)value (’1’,’2’,’2’);-- 驗證事支持DELETE from aaa where uuid != ’1’;insert into aaa (uuid,systemcode,status)value (’2’,’2’,’2’);SELECT * FROM aaa;

排查過程共查找了下述方面:

1、排除數據庫原因:

Spring事務管理配置文件問題排查

查看mysql數據庫是支持事務的;而且用informix數據庫進行了驗證,同樣沒有回滾。

2、驗證了impl的類型等均為問題。

3、查看了事務的配置信息也正確好用。

4、驗證了系統其它的一些方法,發現是支持事務的。

5、將這兩個語句放到其它方法里也好用。

6、事務是在service層處理的,在控制層也加了異常捕獲(這個操作并不會影響事務回滾,即使不catch,也會回滾的)

最終鎖定問題原因:是因為方法名稱的問題。

當將方法名改成其它的,不以get開頭,不報錯。

這個問題很坑,因為本以為為配置文件中的get*,會使這個方法的事務起作用,誰知道恰恰get*的這個配置雖然起作用了,但是結果卻是事務不回滾,在將該配置改為

<tx:method name='get*' propagation='SUPPORTS' rollback-for='java.lang.Exception'/>

也沒有用,最后將其注釋掉,事務回滾。走了下面的配置:

<tx:method name='*' propagation='REQUIRED' rollback-for='java.lang.Exception' />

需要注意的是tx:method 的name屬性指的是方法名。

將SUPPORTS改為REQUIRED后,事務也進行回滾。最終得到原因:是因為propagation的配置信息不正確。

拓展:

一、在聲明式的事務處理中,要配置一個切面,其中就用到了propagation,表示打算對這些方法怎么使用事務,是用還是不用,其中propagation有七種配置,REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED。默認是REQUIRED。

二、Spring中七種Propagation類的事務屬性詳解:

REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。 SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執行。 MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常。 REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。 NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。 NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。 NESTED:支持當前事務,如果當前事務存在,則執行一個嵌套事務,如果當前沒有事務,就新建一個事務。

三、注意.

這個配置將影響數據存儲,必須根據情況選擇。

問題往往出現在你忽略的地方。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
主站蜘蛛池模板: 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 气动调节阀,电动调节阀,自力式压力调节阀,切断阀「厂家」-浙江利沃夫自控阀门 | 青岛侦探_青岛侦探事务所_青岛劝退小三_青岛调查出轨取证公司_青岛婚外情取证-青岛探真调查事务所 | 三佳互联一站式网站建设服务|网站开发|网站设计|网站搭建服务商 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 橡胶膜片,夹布膜片,橡胶隔膜密封,泵阀设备密封膜片-衡水汉丰橡塑科技公司网站 | 物流之家新闻网-最新物流新闻|物流资讯|物流政策|物流网-匡匡奈斯物流科技 | 窖井盖锯圆机_锯圆机金刚石锯片-无锡茂达金刚石有限公司 | 硬度计_影像测量仪_维氏硬度计_佛山市精测计量仪器设备有限公司厂家 | 沈阳楼承板_彩钢板_压型钢板厂家-辽宁中盛绿建钢品股份有限公司 轴承振动测量仪电箱-轴承测振动仪器-测试仪厂家-杭州居易电气 | 电动葫芦-河北悍象起重机械有限公司 | 工控机,嵌入式主板,工业主板,arm主板,图像采集卡,poe网卡,朗锐智科 | 学叉车培训|叉车证报名|叉车查询|叉车证怎么考-工程机械培训网 | 灌木树苗-绿化苗木-常绿乔木-价格/批发/基地 - 四川成都途美园林 | 复合肥,化肥厂,复合肥批发,化肥代理,复合肥品牌-红四方 | 振动筛-交叉筛-螺旋筛-滚轴筛-正弦筛-方形摇摆筛「新乡振动筛厂家」 | 卡诺亚轻高定官网_卧室系统_整家定制_定制家居_高端定制_全屋定制加盟_定制家具加盟_定制衣柜加盟 | 轻型地埋电缆故障测试仪,频响法绕组变形测试仪,静荷式卧式拉力试验机-扬州苏电 | 铸铝门厂家,别墅大门庭院大门,别墅铸铝门铜门[十大品牌厂家]军强门业 | 彼得逊采泥器-定深式采泥器-电动土壤采样器-土壤样品风干机-常州索奥仪器制造有限公司 | 减速机_上海宜嘉减速机| PVC快速门-硬质快速门-洁净室快速门品牌厂家-苏州西朗门业 | 飞飞影视_热门电影在线观看_影视大全 | 制丸机,小型中药制丸机,全自动制丸机价格-甘肃恒跃制药设备有限公司 | 机械加工_绞车配件_立式离心机_减速机-洛阳三永机械厂 | 全自动贴标机-套标机-工业热风机-不干胶贴标机-上海厚冉机械 | 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 净化车间装修_合肥厂房无尘室设计_合肥工厂洁净工程装修公司-安徽盛世和居装饰 | 123悬赏网_发布悬赏任务_广告任务平台 | 标准光源箱|对色灯箱|色差仪|光泽度仪|涂层测厚仪_HRC大品牌生产厂家 | 线粒体膜电位荧光探针-细胞膜-标记二抗-上海复申生物科技有限公司 | 广东成考网-广东成人高考网 | 臭氧灭菌箱-油桶加热箱-原料桶加热融化烘箱-南京腾阳干燥设备厂 臭氧发生器_臭氧消毒机 - 【同林品牌 实力厂家】 | 广东恩亿梯电源有限公司【官网】_UPS不间断电源|EPS应急电源|模块化机房|电动汽车充电桩_UPS电源厂家(恩亿梯UPS电源,UPS不间断电源,不间断电源UPS) | 电动葫芦|防爆钢丝绳电动葫芦|手拉葫芦-保定大力起重葫芦有限公司 | 数显水浴恒温振荡器-分液漏斗萃取振荡器-常州市凯航仪器有限公司 | 洗石机-移动滚筒式,振动,螺旋,洗矿机-青州冠诚重工机械有限公司 | 北京租车公司_汽车/客车/班车/大巴车租赁_商务会议/展会用车/旅游大巴出租_北京桐顺创业租车公司 | 钛合金标准件-钛合金螺丝-钛管件-钛合金棒-钛合金板-钛合金锻件-宝鸡远航钛业有限公司 | 湖州织里童装_女童男童中大童装_款式多尺码全_织里儿童网【官网】-嘉兴嘉乐网络科技有限公司 | COD分析仪|氨氮分析仪|总磷分析仪|总氮分析仪-圣湖Greatlake | 杭州用友|用友软件|用友财务软件|用友ERP系统--杭州协友软件官网 |