กำลังแสดงธุรกรรม Spring ในบันทึก


104

ฉันกำหนดค่าสปริงด้วยการรองรับธุรกรรม มีวิธีใดในการบันทึกธุรกรรมเพื่อให้แน่ใจว่าฉันตั้งค่าทุกอย่างถูกต้องหรือไม่? การแสดงในบันทึกเป็นวิธีที่ดีในการดูสิ่งที่เกิดขึ้น

คำตอบ:


96

ในของคุณlog4j.properties(สำหรับผู้ตัดไม้ทางเลือกหรือรูปแบบ xml ของ log4j ให้ตรวจสอบเอกสาร)

ขึ้นอยู่กับตัวจัดการธุรกรรมของคุณคุณสามารถตั้งค่าระดับการบันทึกของกรอบงานสปริงเพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับธุรกรรม ตัวอย่างเช่นในกรณีที่ใช้JpaTransactionManagerคุณตั้งค่า

log4j.logger.org.springframework.orm.jpa=INFO

(นี่คือแพ็คเกจของผู้จัดการธุรกรรมของคุณ) และ

log4j.logger.org.springframework.transaction=INFO

หากINFOไม่เพียงพอให้ใช้DEBUG


7
INFOระดับจะไม่แสดงกิจกรรม tx เลยมันจะดูละเอียดเกินไป DEBUGจะมีความจำเป็นที่นั่น
skaffman

@Bozho ฉัน JpaTransactionManager และฉันต้องการตรวจสอบเมื่อมีการยืมการเชื่อมต่อจากพูลและเมื่อมีการเปิดตัวสำหรับธุรกรรมเฉพาะ
Ali

จากนั้นคุณจะต้องเปลี่ยนการกำหนดค่าการบันทึกสำหรับพูลการเชื่อมต่อของคุณ
Bozho

จะเป็นอย่างไรหากเราใช้ mybatis + slf4j + logback + springboot
ดอกลิลลี่

67

สำหรับฉันการกำหนดค่าการบันทึกที่ดีที่จะเพิ่มคือ:

log4j.logger.org.springframework.transaction.interceptor = trace

มันจะแสดงให้ฉันเห็นบันทึกเช่นนั้น:

2012-08-22 18: 50: 00,031 TRACE - การรับธุรกรรมสำหรับ [com.MyClass.myMethod]

[คำสั่งบันทึกของฉันเองจากวิธี com.MyClass.myMethod]

2012-08-22 18: 50: 00,142 TRACE - การทำธุรกรรมให้เสร็จสมบูรณ์สำหรับ [com.MyClass.myMethod]


1
เยี่ยมมาก! ไม่จำเป็นต้องมีการบันทึกข้อมูล / ดีบัก / ติดตามทั้งหมดของแพ็คเกจอื่น ๆ เมื่อนี่คือสิ่งที่คุณกำลังมองหา: D
Johanneke

34

สำหรับแอปพลิเคชัน Spring Boot ด้วยไฟล์ application.properties

logging.level.ROOT=INFO
logging.level.org.springframework.orm.jpa=DEBUG
logging.level.org.springframework.transaction=DEBUG

หรือถ้าคุณชอบ Yaml ( application.yaml)

logging:
   level:
      org.springframework.orm.jpa: DEBUG
      org.springframework.transaction: DEBUG

1
ทำงานได้อย่างมีเสน่ห์
Ben

9

ข้อมูลบันทึกที่น่าสนใจที่สุดของJtaTransactionManager.java(หากคำถามนี้ยังคงเกี่ยวกับJtaTransactionManager) จะถูกบันทึกตามDEBUGลำดับความสำคัญ สมมติว่าคุณมีlog4j.propertiesที่ไหนสักแห่งบน classpath ฉันขอแนะนำให้ใช้:

log4j.logger.org.springframework.transaction=DEBUG

7

เนื่องจากคุณสามารถเข้าถึงคลาส Spring ที่รันไทม์คุณจึงสามารถกำหนดสถานะธุรกรรมได้ บทความนี้อาจช่วยคุณ:

https://dzone.com/articles/monitoring-declarative-transac


เสียมาก แต่ลอง: เคล็ดลับในการแก้จุดบกพร่อง @Transactional Annotation ของ Spring (ยังไม่ได้ลองด้วยตัวเอง) ใช้TransactionSynchronizationManagerเพื่อรับสถานะธุรกรรม โค้ดควรใช้ตัวแปรเธรดโลคัลเพื่อแคชการอ้างอิงisActualTransactionActive()แทนการดึงข้อมูลในการเรียกบันทึกแต่ละครั้ง
David Tonhofer


1

นี่คือบางส่วนใช้ฉันรหัสในการดำเนิน Logback เค้าโครงของฉันมาจากch.qos.logback.core.LayoutBase

org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive()ฉันจะสร้างตัวแปรด้ายท้องถิ่นในการจัดเก็บการอ้างอิงถึงวิธีการ เมื่อใดก็ตามที่พิมพ์บรรทัดบันทึกใหม่จะgetSpringTransactionInfo()ถูกเรียกและจะส่งคืนสตริงอักขระเดียวที่จะเข้าสู่บันทึก

อ้างอิง:

รหัส:

private static ThreadLocal<Method> txCheckMethod;

private static String getSpringTransactionInfo() {
    if (txCheckMethod == null) {
        txCheckMethod = new ThreadLocal<Method>() {
            @Override public Method initialValue() {           
                try {
                    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
                    Class<?> tsmClass = contextClassLoader.loadClass("org.springframework.transaction.support.TransactionSynchronizationManager");
                    return tsmClass.getMethod("isActualTransactionActive", (Class<?>[])null);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }                      
            }
         };    
    }
    assert txCheckMethod != null;
    Method m = txCheckMethod.get();
    String res;
    if (m == null) {
        res = " "; // there is no Spring here
    }
    else {
        Boolean isActive = null;
        try {
            isActive = (Boolean) m.invoke((Object)null);
            if (isActive) {
                res = "T"; // transaction active                    
            }
            else {
                res = "~"; // transaction inactive
            }
        }
        catch (Exception exe) {
            // suppress 
            res = "?";
        }
    }
    return res;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.