127.0.0.1:9200
URL: http://127.0.0.1:9200/likecs_art_db/_search
REQUEST:
Array
(
    [query] => Array
        (
            [match] => Array
                (
                    [text] => Array
                        (
                            [query] => 一次Spring Transactional嵌套事务使用不同的rollbackFor的分析
                        )

                )

        )

    [highlight] => Array
        (
            [fields] => Array
                (
                    [text] => stdClass Object
                        (
                        )

                )

            [pre_tags] => #em#
            [post_tags] => #/em#
        )

    [size] => 8
    [from] => 0
)
RESPONSE:
string(8659) "{"took":80,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":10000,"relation":"gte"},"max_score":67.46037,"hits":[{"_index":"likecs_art_db","_type":"_doc","_id":"23338","_score":67.46037,"_source":{"id":"23338","text":"\u4e00\u6b21Spring Transactional\u5d4c\u5957\u4e8b\u52a1\u4f7f\u7528\u4e0d\u540c\u7684rollbackFor\u7684\u5206\u6790","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"null-qige","tagsname":"","tagsid":"[]","catesname":"mysql\u5b66\u4e60\u7b14\u8bb0","catesid":"[\"1991\"]","createtime":"1530267086"},"highlight":{"text":["#em#一#/em##em#次#/em##em#Spring#/em# #em#Transactional#/em##em#嵌#/em##em#套#/em##em#事#/em##em#务#/em##em#使#/em##em#用#/em##em#不#/em##em#同#/em##em#的#/em##em#rollbackFor#/em##em#的#/em##em#分#/em##em#析#/em#"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"25451","_score":32.71175,"_source":{"id":"25451","text":"Spring\u4e2d\u7684@Transactional(rollbackFor = Exception.class)\u5c5e\u6027\u8be6\u89e3","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"clwydjgs","tagsname":"\u6ce8\u89e3|spring","tagsid":"[\"4047\",\"696\"]","catesname":"","catesid":"[]","createtime":"1531725811"},"highlight":{"text":["#em#Spring#/em#中#em#的#/em#@#em#Transactional#/em#(#em#rollbackFor#/em# = Exception.class)属性详解"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203287303","_score":32.055813,"_source":{"id":"203287303","text":"spring\u4e8b\u52a1@Transactional\u5728\u540c\u4e00\u4e2a\u7c7b\u4e2d\u7684\u65b9\u6cd5\u8c03\u7528\u4e0d\u751f\u6548","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1618531498"},"highlight":{"text":["#em#spring#/em##em#事#/em##em#务#/em#@#em#Transactional#/em#在#em#同#/em##em#一#/em#个类中#em#的#/em#方法调#em#用#/em##em#不#/em#生效"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203464093","_score":31.077633,"_source":{"id":"203464093","text":"spring\u58f0\u660e\u5f0f\u6ce8\u89e3@Transactional\u7684rollbackFor\u5c5e\u6027\u7684\u7528\u6cd5\u548c\u6ce8\u610f\u4e8b\u9879","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1618269633"},"highlight":{"text":["#em#spring#/em#声明式注解@#em#Transactional#/em##em#的#/em##em#rollbackFor#/em#属性#em#的#/em##em#用#/em#法和注意#em#事#/em#项"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203464080","_score":29.774384,"_source":{"id":"203464080","text":"Spring \u4e8b\u52a1\u6ce8\u89e3\u00a0@Transactional \u4f7f\u7528\u65b9\u5f0f","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1624762051"},"highlight":{"text":["#em#Spring#/em# #em#事#/em##em#务#/em#注解 @#em#Transactional#/em# #em#使#/em##em#用#/em#方式"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"116734","_score":28.573837,"_source":{"id":"116734","text":"Spring\u5b98\u65b9\u90fd\u63a8\u8350\u4f7f\u7528\u7684@Transactional\u4e8b\u52a1\uff0c\u4e3a\u5565\u6211\u4e0d\u5efa\u8bae\u4f7f\u7528\uff01","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"hollischuang","tagsname":"","tagsid":"[]","catesname":"","catesid":"[]","createtime":"1603072934"},"highlight":{"text":["#em#Spring#/em#官方都推荐#em#使#/em##em#用#/em##em#的#/em#@#em#Transactional#/em##em#事#/em##em#务#/em#,为啥我#em#不#/em#建议#em#使#/em##em#用#/em#!"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203529672","_score":28.192099,"_source":{"id":"203529672","text":"Spring\u63d0\u53d6@Transactional\u4e8b\u52a1\u6ce8\u89e3\u7684\u6e90\u7801\u89e3\u6790","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1637869335"},"highlight":{"text":["#em#Spring#/em#提取@#em#Transactional#/em##em#事#/em##em#务#/em#注解#em#的#/em#源码解#em#析#/em#"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203426293","_score":27.885176,"_source":{"id":"203426293","text":"Spring\u4e8b\u52a1\u7ba1\u7406\u5d4c\u5957\u4e8b\u52a1\u8be6\u89e3 : \u540c\u4e00\u4e2a\u7c7b\u4e2d\uff0c\u4e00\u4e2a\u65b9\u6cd5\u8c03\u7528\u53e6\u5916\u4e00\u4e2a\u6709\u4e8b\u52a1\u7684\u65b9\u6cd5","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1628906875"},"highlight":{"text":["#em#Spring#/em##em#事#/em##em#务#/em#管理#em#嵌#/em##em#套#/em##em#事#/em##em#务#/em#详解 : #em#同#/em##em#一#/em#个类中,#em#一#/em#个方法调#em#用#/em#另外#em#一#/em#个有#em#事#/em##em#务#/em##em#的#/em#方法"]}}]}}"
127.0.0.1:9200
URL: http://127.0.0.1:9200/likecs_art_db/_search
REQUEST:
Array
(
    [query] => Array
        (
            [match] => Array
                (
                    [text] => Array
                        (
                            [query] => 一次Spring Transactional嵌套事务使用不同的rollbackFor的分析
                        )

                )

        )

    [highlight] => Array
        (
            [fields] => Array
                (
                    [text] => stdClass Object
                        (
                        )

                )

            [pre_tags] => #em#
            [post_tags] => #/em#
        )

    [size] => 8
    [from] => 8
)
RESPONSE:
string(7925) "{"took":92,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":10000,"relation":"gte"},"max_score":67.46037,"hits":[{"_index":"likecs_art_db","_type":"_doc","_id":"203464102","_score":26.519278,"_source":{"id":"203464102","text":"spring\u6ce8\u89e3@transactional\u4e8b\u52a1\u4f20\u64ad","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1623694018"},"highlight":{"text":["#em#spring#/em#注解@#em#transactional#/em##em#事#/em##em#务#/em#传播"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203464107","_score":26.519278,"_source":{"id":"203464107","text":"Spring\u4e8b\u52a1\u6ce8\u89e3Transactional\u5931\u6548","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1621646003"},"highlight":{"text":["#em#Spring#/em##em#事#/em##em#务#/em#注解#em#Transactional#/em#失效"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203279258","_score":26.34633,"_source":{"id":"203279258","text":"SpringBoot\u4f7f\u7528@Async\u6ce8\u89e3\u5931\u6548\u5206\u6790\uff08@Transactional\u4e8b\u52a1\u6ce8\u89e3\u5931\u6548\u5206\u6790\uff09","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1638768127"},"highlight":{"text":["SpringBoot#em#使#/em##em#用#/em#@Async注解失效#em#分#/em##em#析#/em#(@#em#Transactional#/em##em#事#/em##em#务#/em#注解失效#em#分#/em##em#析#/em#)"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203279259","_score":26.34633,"_source":{"id":"203279259","text":"SpringBoot\u4f7f\u7528@Async\u6ce8\u89e3\u5931\u6548\u5206\u6790\uff08@Transactional\u4e8b\u52a1\u6ce8\u89e3\u5931\u6548\u5206\u6790\uff09","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1626937744"},"highlight":{"text":["SpringBoot#em#使#/em##em#用#/em#@Async注解失效#em#分#/em##em#析#/em#(@#em#Transactional#/em##em#事#/em##em#务#/em#注解失效#em#分#/em##em#析#/em#)"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"62961","_score":26.071175,"_source":{"id":"62961","text":"MySQL \u4e8b\u52a1\u5d4c\u5957","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"zhoutianyuan","tagsname":"","tagsid":"[]","catesname":"MySQL|PHP","catesid":"[\"132\",\"179\"]","createtime":"1561962715"},"highlight":{"text":["MySQL #em#事#/em##em#务#/em##em#嵌#/em##em#套#/em#"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"121522","_score":25.875141,"_source":{"id":"121522","text":"SQLServer\u591a\u4e8b\u52a1\u2014\u2014\u4e8b\u52a1\u5d4c\u5957","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"teemi","tagsname":"","tagsid":"[]","catesname":"SQLServer","catesid":"[\"1560\"]","createtime":"1609169909"},"highlight":{"text":["SQLServer多#em#事#/em##em#务#/em#——#em#事#/em##em#务#/em##em#嵌#/em##em#套#/em#"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"135351","_score":25.569975,"_source":{"id":"135351","text":"Spring @Transactional \u6ce8\u89e3\u662f\u5982\u4f55\u6267\u884c\u4e8b\u52a1\u7684\uff1f","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"liuzhihang","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1631323876"},"highlight":{"text":["#em#Spring#/em# @#em#Transactional#/em# 注解是如何执行#em#事#/em##em#务#/em##em#的#/em#?"]}},{"_index":"likecs_art_db","_type":"_doc","_id":"203519540","_score":25.478716,"_source":{"id":"203519540","text":"\u540c\u4e00\u4e2amoduel\u4e2d\u4f7f\u7528\u4e24\u5957\u4e0d\u540c\u7684jniLibs","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n    color: [\r\n        ","username":"","tagsname":null,"tagsid":"","catesname":null,"catesid":"","createtime":"1641996528"},"highlight":{"text":["#em#同#/em##em#一#/em#个moduel中#em#使#/em##em#用#/em#两#em#套#/em##em#不#/em##em#同#/em##em#的#/em#jniLibs"]}}]}}"
127.0.0.1:9200
URL: http://192.168.101.128/searchcore/index.php/cihere_cn_db/_search
REQUEST:
Array
(
    [query] => Array
        (
            [match] => Array
                (
                    [title] => Array
                        (
                            [query] => 一次Spring Transactional嵌套事务使用不同的rollbackFor的分析
                        )

                )

        )

    [highlight] => Array
        (
            [fields] => Array
                (
                    [title] => stdClass Object
                        (
                        )

                )

            [pre_tags] => #em#
            [post_tags] => #/em#
        )

    [from] => 0
)
RESPONSE:
bool(false)
127.0.0.1:9200
URL: http://127.0.0.1:9200/likecs_down_db/_search
REQUEST:
Array
(
    [query] => Array
        (
            [bool] => Array
                (
                    [must] => Array
                        (
                            [0] => Array
                                (
                                    [match] => Array
                                        (
                                            [title] => Array
                                                (
                                                    [query] => 一次Spring Transactional嵌套事务使用不同的rollbackFor的分析
                                                )

                                        )

                                )

                        )

                    [must_not] => Array
                        (
                            [0] => Array
                                (
                                    [term] => Array
                                        (
                                            [cate1] => 电子书籍
                                        )

                                )

                        )

                )

        )

    [highlight] => Array
        (
            [fields] => Array
                (
                    [title] => stdClass Object
                        (
                        )

                )

            [pre_tags] => #em#
            [post_tags] => #/em#
        )

    [size] => 5
    [from] => 0
)
RESPONSE:
string(3382) "{"took":9,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":10000,"relation":"gte"},"max_score":20.958006,"hits":[{"_index":"likecs_down_db","_type":"_doc","_id":"71769","_score":20.958006,"_source":{"id":"71769","title":"Selenium WebDriver \u4e2d\u7684\u4e00\u4e9b\u9f20\u6807\u548c\u952e\u76d8\u4e8b\u4ef6\u7684\u4f7f\u7528 \u4e2d\u6587WORD\u7248","spidertime":"1623127552","contenttime":"1672031201","pageimage":"https:\/\/img.jbzj.com\/do\/uploads\/litimg\/160922\/09143Ac525.png","tag":"Selenium|webdriver|\u9f20\u6807\u4f7f\u7528|\u952e\u76d8\u4f7f\u7528","cate1":"\u7535\u5b50\u4e66\u7c4d","cate2":"\u7f51\u7edc\u76f8\u5173","attr1":"63.2KB"},"highlight":{"title":["Selenium WebDriver 中#em#的#/em##em#一#/em#些鼠标和键盘#em#事#/em#件#em#的#/em##em#使#/em##em#用#/em# 中文WORD版"]}},{"_index":"likecs_down_db","_type":"_doc","_id":"36744","_score":20.958006,"_source":{"id":"36744","title":"Selenium WebDriver \u4e2d\u7684\u4e00\u4e9b\u9f20\u6807\u548c\u952e\u76d8\u4e8b\u4ef6\u7684\u4f7f\u7528 \u4e2d\u6587WORD\u7248","spidertime":"1622961906","contenttime":"1622961906","pageimage":"https:\/\/img.jbzj.com\/do\/uploads\/litimg\/160922\/09143Ac525.png","tag":"Selenium|webdriver|\u9f20\u6807\u4f7f\u7528|\u952e\u76d8\u4f7f\u7528","cate1":"\u7535\u5b50\u4e66\u7c4d","cate2":"\u7f51\u7edc\u76f8\u5173","attr1":"63.2KB"},"highlight":{"title":["Selenium WebDriver 中#em#的#/em##em#一#/em#些鼠标和键盘#em#事#/em#件#em#的#/em##em#使#/em##em#用#/em# 中文WORD版"]}},{"_index":"likecs_down_db","_type":"_doc","_id":"51032","_score":20.541763,"_source":{"id":"51032","title":"\u5728Spring\u4e2d\u5b9e\u73b0\u7f16\u7a0b\u5f0f\u7684\u4e8b\u52a1\u7ba1\u7406 WORD\u7248","spidertime":"1623055175","contenttime":"1672618908","pageimage":"https:\/\/img.jbzj.com\/do\/uploads\/litimg\/170123\/0R225591263.png","tag":"Spring|\u7f16\u7a0b\u5f0f|\u4e8b\u52a1\u7ba1\u7406","cate1":"\u7535\u5b50\u4e66\u7c4d","cate2":"\u7f16\u7a0b\u5f00\u53d1","cate3":"java\u7535\u5b50\u4e66","attr1":"212KB"},"highlight":{"title":["在#em#Spring#/em#中实现编程式#em#的#/em##em#事#/em##em#务#/em#管理 WORD版"]}},{"_index":"likecs_down_db","_type":"_doc","_id":"101331","_score":20.541763,"_source":{"id":"101331","title":"\u5728Spring\u4e2d\u5b9e\u73b0\u7f16\u7a0b\u5f0f\u7684\u4e8b\u52a1\u7ba1\u7406 WORD\u7248","spidertime":"1625737839","contenttime":"1625859474","pageimage":"https:\/\/img.jbzj.com\/do\/uploads\/litimg\/170123\/0R225591263.png","tag":"Spring|\u7f16\u7a0b\u5f0f|\u4e8b\u52a1\u7ba1\u7406","cate1":"\u7535\u5b50\u4e66\u7c4d","cate2":"\u7f16\u7a0b\u5f00\u53d1","cate3":"java\u7535\u5b50\u4e66","attr1":"212KB"},"highlight":{"title":["在#em#Spring#/em#中实现编程式#em#的#/em##em#事#/em##em#务#/em#管理 WORD版"]}},{"_index":"likecs_down_db","_type":"_doc","_id":"59198","_score":18.326233,"_source":{"id":"59198","title":"\u4f7f\u7528Repeater\u5b9e\u73b0\u5206\u9875\u7684\u9875\u7801 WORD\u7248","spidertime":"1623066486","contenttime":"1678754701","pageimage":"https:\/\/img.jbzj.com\/do\/uploads\/litimg\/170120\/164624594525.png","tag":"Repeater|\u5b9e\u73b0\u5206\u9875|\u9875\u7801","cate1":"\u7535\u5b50\u4e66\u7c4d","cate2":"\u5176\u5b83\u76f8\u5173","attr1":"340KB"},"highlight":{"title":["#em#使#/em##em#用#/em#Repeater实现#em#分#/em#页#em#的#/em#页码 WORD版"]}}]}}"
一次Spring Transactional嵌套事务使用不同的rollbackFor的分析 - 爱码网
null-qige

一次Spring Transactional嵌套事务使用不同的rollbackFor的分析

  起因:

    项目期间由于一次异常回滚问题,发现自己在事务知识方面知识的遗漏,趁着这次机会,做了几次rollbackFor的测试。

  

  测试:

     现在有两个事务,事务oute包含事务Inner。事务A回滚规则是当事务抛出TestException,其中TestException继承RunTimeException。事务B的回滚规则是事务抛RuntimeException。事务的传播方式都是使用的默认,即 Propagation.REQUIRED。如以下代码:

 

 1     @Override
 2     @Transactional(rollbackFor = TestException.class)
 3     public void transOuter() {
 4         productMapper.updateOrderQuantityPessimistic(product_code1);
 5         ((ProductService) AopContext.currentProxy()).transInner();
 6     }
 7 
 8     @Transactional(rollbackFor = Exception.class)
 9     public void transInner() {
10         productMapper.updateOrderQuantityPessimistic(product_code);
11         if (true) {
12             throw new RuntimeException();
13         }
14     }

 

    以下为TestException的代码。

1 public class TestException extends RuntimeException {
2 
3     public TestException(String message) {
4         super(message);
5     }
6 }

 

   一开始按照自己对事务的理解, 默认的传播属性之下。事务B启动的时候,会默认使用事务A的rollbackFor来进行回滚,所以该代码运行时候。程序不会回滚。

   然而测试,测试完之后发现事务A、B都进行了回滚。

   看着测试结果产生了疑问。难道是以innner的rollBack为准?接着进行测试。

 

 1     @Override
 2     @Transactional(rollbackFor = Exception.class)
 3     public void transOuter() {
 4         productMapper.updateOrderQuantityPessimistic(product_code1);
 5         ((ProductService) AopContext.currentProxy()).transInner();
 6     }
 7 
 8     @Transactional(rollbackFor = TestException.class)
 9     public void transInner() {
10         productMapper.updateOrderQuantityPessimistic(product_code);
11         if (true) {
12             throw new RuntimeException();
13         }
14     }

 

    再次测试,测试完之后发现事务A、B依然进行了回滚。

    感觉自己对事务的理解还是太浅薄了,是时候debug一波源码。

 

  分析源码:

  查看  org.springframework.transaction.interceptor.TransactionAspectSupport 类的 invokeWithinTransaction方法。该方法是事务执行的主要方法,这里我们主要看第20行的事务捕捉那一块。completeTransactionAfterThrowing的方法。

 1     protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
 2             throws Throwable {
 3 
 4         // If the transaction attribute is null, the method is non-transactional.
 5         final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
 6         final PlatformTransactionManager tm = determineTransactionManager(txAttr);
 7         final String joinpointIdentification = methodIdentification(method, targetClass);
 8 
 9         if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
10             // Standard transaction demarcation with getTransaction and commit/rollback calls.
11             TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
12             Object retVal = null;
13             try {
14                 // This is an around advice: Invoke the next interceptor in the chain.
15                 // This will normally result in a target object being invoked.
16                 retVal = invocation.proceedWithInvocation();
17             }
18             catch (Throwable ex) {
19                 // 事务异常捕捉主要在这边获取
20                 completeTransactionAfterThrowing(txInfo, ex);
21                 throw ex;
22             }
23             finally {
24                 cleanupTransactionInfo(txInfo);
25             }
26             commitTransactionAfterReturning(txInfo);
27             return retVal;
28         }
29 
30         else {
31             // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
32             try {
33                 Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
34                         new TransactionCallback<Object>() {
35                             @Override
36                             public Object doInTransaction(TransactionStatus status) {
37                                 TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
38                                 try {
39                                     return invocation.proceedWithInvocation();
40                                 }
41                                 catch (Throwable ex) {
42                                     if (txAttr.rollbackOn(ex)) {
43                                         // A RuntimeException: will lead to a rollback.
44                                         if (ex instanceof RuntimeException) {
45                                             throw (RuntimeException) ex;
46                                         }
47                                         else {
48                                             throw new ThrowableHolderException(ex);
49                                         }
50                                     }
51                                     else {
52                                         // A normal return value: will lead to a commit.
53                                         return new ThrowableHolder(ex);
54                                     }
55                                 }
56                                 finally {
57                                     cleanupTransactionInfo(txInfo);
58                                 }
59                             }
60                         });
61 
62                 // Check result: It might indicate a Throwable to rethrow.
63                 if (result instanceof ThrowableHolder) {
64                     throw ((ThrowableHolder) result).getThrowable();
65                 }
66                 else {
67                     return result;
68                 }
69             }
70             catch (ThrowableHolderException ex) {
71                 throw ex.getCause();
72             }
73         }
74     }

 

  这边显示当事务的rollbackFor为TestException,而抛出的异常为RunTimeException时候。跟我们的transInner一致。接着往下看 completeTransactionAfterThrowing 方法。主要看第8行,第8行对事务进行判断,是否对该抛出的异常进行回滚。

 1 protected void completeTransactionAfterThrowing(TransactionAspectSupport.TransactionInfo txInfo, Throwable ex) {
 2         if (txInfo != null && txInfo.hasTransaction()) {
 3             if (logger.isTraceEnabled()) {
 4                 logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
 5                         "] after exception: " + ex);
 6             }
 7             //这里主要判断事务捕获了异常以后,是否进行回滚
 8             if (txInfo.transactionAttribute.rollbackOn(ex)) {
 9                 try {
10                     txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
11                 }
12                 catch (TransactionSystemException ex2) {
13                     logger.error("Application exception overridden by rollback exception", ex);
14                     ex2.initApplicationException(ex);
15                     throw ex2;
16                 }
17                 catch (RuntimeException ex2) {
18                     logger.error("Application exception overridden by rollback exception", ex);
19                     throw ex2;
20                 }
21                 catch (Error err) {
22                     logger.error("Application exception overridden by rollback error", ex);
23                     throw err;
24                 }
25             }
26             else {
27                 // We don't roll back on this exception.
28                 // Will still roll back if TransactionStatus.isRollbackOnly() is true.
29                 try {
30                     txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
31                 }
32                 catch (TransactionSystemException ex2) {
33                     logger.error("Application exception overridden by commit exception", ex);
34                     ex2.initApplicationException(ex);
35                     throw ex2;
36                 }
37                 catch (RuntimeException ex2) {
38                     logger.error("Application exception overridden by commit exception", ex);
39                     throw ex2;
40                 }
41                 catch (Error err) {
42                     logger.error("Application exception overridden by commit error", ex);
43                     throw err;
44                 }
45             }
46         }
47     }

    

    再深入点进去看,看到第11行,这边获取该异常的深度。跳转到片段二进行代码查看。

 1     public boolean rollbackOn(Throwable ex) {
 2         if (logger.isTraceEnabled()) {
 3             logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
 4         }
 5 
 6         RollbackRuleAttribute winner = null;
 7         int deepest = Integer.MAX_VALUE;
 8 
 9         if (this.rollbackRules != null) {
10             for (RollbackRuleAttribute rule : this.rollbackRules) {
11                 //获取异常的深度?
12                 int depth = rule.getDepth(ex);
13                 if (depth >= 0 && depth < deepest) {
14                     deepest = depth;
15                     winner = rule;
16                 }
17             }
18         }
19 
20         if (logger.isTraceEnabled()) {
21             logger.trace("Winning rollback rule is: " + winner);
22         }
23 
24         // User superclass behavior (rollback on unchecked) if no rule matches.
25         if (winner == null) {
26             logger.trace("No relevant rollback rule found: applying default rules");
27             //如果depth为-1之后,父类的回滚方式
28             return super.rollbackOn(ex);
29         }
30 
31         return !(winner instanceof NoRollbackRuleAttribute);
32     }

    

    根据深度代码查看,rollbackFor和抛出异常ex不一致,返回-1。再回去看上面的代码片段,当返回-1之后,代码走到第28行。进行父类的回滚方法。

 1     private int getDepth(Class<?> exceptionClass, int depth) {
 2         if (exceptionClass.getName().contains(this.exceptionName)) {
 3             // Found it!
 4             return depth;
 5         }
 6         // If we've gone as far as we can go and haven't found it...
 7         //此处RuntimeException 跟TestException不一致,返回-1
 8         if (exceptionClass == Throwable.class) {
 9             return -1;
10         }
11         return getDepth(exceptionClass.getSuperclass(), depth + 1);
12     }

    

    以下是父类的代码是否回滚判断方法,有没有很眼熟,只要抛出的异常的是RunTimeExcpetion或者Error则进行回滚。

1     public boolean rollbackOn(Throwable ex) {
2         return (ex instanceof RuntimeException || ex instanceof Error);
3     }

 

  

  总结

    根据上面的代码,我们可以推断出以下几个结论:

    1、当我们抛出的异常为RunTime及其子类或者Error和其子类的时候。不论rollbackFor的异常是啥,都会进行事务的回滚。

    2、当我们抛出的异常不是RunTime及其子类或者Error和其子类的时候,必须根据rollbackfor进行回滚。比如rollbackfor=RuntimeException,而抛出IOException时候,事务是不进行回滚的。

    3、当我们抛出的异常不是RunTime及其子类或者Error和其子类的时候,如果嵌套事务中,只要有一个rollbackfor允许回滚,则整个事务回滚。

    经过测试,上述的结论也没发现什么问题。

 

  

posted on 2018-06-29 18:03 阿姆斯特朗回旋炮 阅读(...) 评论(...) 编辑 收藏

相关文章:

  • 2021-06-15
  • 2021-05-22
  • 2021-12-06
  • 2019-07-01
  • 2020-12-28
  • 2021-09-11
  • 2022-01-12
猜你喜欢
  • 2018-07-16
  • 2021-04-16
  • 2021-04-13
  • 2021-06-27
  • 2020-10-19
  • 2021-11-26
  • 2021-08-14
相关资源
相似解决方案