Observability of the Java Virtual Machine

Image
The JVM is one of the most observable runtimes. It provides us lots of tools for troubleshooting a JVM application in production. 1. Thread observability Threads are how the JVM actually does work. When something is wrong in production, the symptom is almost always a thread: stopped, blocked, leaking etc. Thread dumps work on any JVM with no  instrumentation, no agents, no restarts. <Example project link with /threaddump endpoint>         // (1) Deadlock — two threads grab the same pair of locks in opposite order.         new Thread(() -> grab(LOCK_A, LOCK_B), "deadlock-A-then-B").start();         new Thread(() -> grab(LOCK_B, LOCK_A), "deadlock-B-then-A").start(); http://localhost:8080/actuator/threaddump To list the JVMS, we can use the command below. PS C:\observe-jvm> jps -lv 25296 jdk.jcmd/sun.tools.jps.Jps -Dapplication.home=C:\Program Files\Microsoft\jdk-21.0.3.9-hotspot -Xms8m -Djdk.module.main=...

Servis sınıfları ile "Transaction" yönetimi

Kurumsal uygulamalarda en önemli konulardan birisi de birbirinden ayrılamaz veritabanı işlemlerinin bir "transaction" içerisinde yapılmasının sağlanmasıdır. Çok katmanlı (layer) uygulamamızda bu işin yapılmasından hangi katman sorumlu olmalıdır? Diğer katmanların durumu nedir?

Yaygın olarak kullanılan "veri erişim nesnesi" (DAO) kalıbını kullandığımızı düşünelim. Bunların yer aldığı veri erişimi katmanı, transaction yönetiminden sorumlu olabilir. Fakat en çok kabul görmüş yöntemlerden birisi, transaction kontrolünün "service layer" denilen bir katmanda yapılmasıdır. Böyle bir yapıda gerçekleşen olaylar şöyle özetlenebilir:

1- Kullanıcı arayüzü katmanına ilişkin "controller" kodu, bir servis metodunu çağırır. Örnek:

class StudentController...

{
//...
studentService.addRegistration(...);

}

Görüldüğü gibi burada kullanıcı arayüzü kodu, sadece tek bir servis metodunu çağırmakta ve gerisine karışmamaktadır. Transaction kontrolünden sorumlu değildir.

2- Servis metodu, yapılacak işlemlerin bir transaction içerisinde atomik olarak yapılmasını sağlar. Bunu yaparken elbette kullanılan platformun transaction kontrolü mekanizmalarından faydalanır. Örneğin Spring çatısının transaction kontrol metotlarını kullanıyorsak:

class StudentService...

{
getTransactionTemplate().execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
//...
getTransactionDao().makePersistent(transaction);

//...
}
});
}


Burada servis metodunun yaptığı şey, yapılan işlemi bir transaction içerisine almaktır. Kırmızı ile boyanmış kodda da gördüğümüz gibi burada veri erişim katmanına ait olan bir DAO sınıfının metodu çağrılıyor. Bu DAO sınıfının kodlarını incelediğimizde, transaction konusundan bihaber olduğunu görürüz. Yani DAO sınıfları veritabanı işlemlerini gerçekleştirirken, transaction içerisinde olunup olunmadığı ile ilgilenmiyorlar.

Çeşitli geliştirme çatılarının sunduğu transaction kontrolü seçeneklerini 2 gruba ayırabiliriz:
1- Programlama yoluyla (programmatic)
2- Bildirimsel olarak (declarative)

Bunlardan hangisini tercih ettiğimiz o kadar önemli değil. Asıl önemli olan, tüm uygulama kodlarının uyduğu bir transaction kontrol kuralının (veya tasarım kalıbının) benimsenmiş olmasıdır. Örneğin yukarıda anlattığımız yöntemde servis metotları sorumluluk almış. Böyle bir tasarım kalıbına "Servis tarafından sahiplenilmiş Transaction (Service Owned Transaction)" ismi verilebilir.

Comments

Popular posts from this blog

The WeakReference class, monitoring memory leak and garbage collection in a Java application

Simplescalar Simulator - Part 2: sim-outorder.c

Notes on Java Performance