İşlemlere neden ihtiyaç duyulur?

Çoğu zaman, bir veritabanıyla çalışırken, birçok farklı eylem gerçekleştirmeniz gerektiğinde bir durum ortaya çıkar, ancak bunlar yalnızca birlikte anlamlıdır.

Örneğin, üç şey yapması gereken bir bankacılık yazılımı yazıyoruz:

  • Müşterinin hesabından para çekme
  • Alıcının hesabına para ekleyin
  • Gönderim verilerini "gönderme günlüğüne" kaydedin

Bu eylemlerden herhangi birinin yürütülmesi sırasında bir hata oluşursa, diğer ikisinin de iptal edilmesi gerekir. Müşteriden parayı yazıp alıcıya eklememek imkansız mı? Peki, ya da alıcıya ekleyin, ancak müşteriden yazmayın mı?

Dolayısıyla, farklı eylemlerin böyle bir mantıksal gruplandırmasına işlem denir . Başka bir deyişle, bir işlem, yalnızca hep birlikte gerçekleştirilmesi gereken bir eylemler grubudur . Herhangi bir eylem başarısız olursa veya bir hatayla gerçekleştirilirse, diğer tüm işlemler iptal edilmelidir.

Bir işlemin genellikle üç durumu vardır:

  • başlangıç ​​durumu - bir grup eylemi gerçekleştirmeden önce sistemin durumu
  • başarı durumu - eylem grubu tamamlandıktan sonraki durum
  • başarısız durum - bir şeyler ters gitti

Bu durumda, genellikle üç komut vardır:

  • start/start - mantıksal eylem grubu başlamadan önce yürütülür
  • taahhüt - işlem eylem grubundan sonra yürütülür
  • geri alma - sistemi başarısız durumdan başlangıç ​​durumuna döndürme işlemini başlatır

Bu şekilde çalışır.

Öncelikle bir işlem açmanız gerekir - begin() veya start() yöntemini çağırın . Bu yöntemi çağırmak, bir şeyler ters giderse geri dönmeye çalışacağımız sistemin durumunu gösterir.

Ardından, mantıksal bir grup olan bir işlemde birleştirilen tüm eylemler gerçekleştirilir.

Daha sonra commit() yöntemi çağrılır . Çağrısı, mantıklı bir eylem grubunun sonunu işaretler ve ayrıca genellikle bu eylemleri uygulamaya koyma sürecini başlatır.

FileWriter'da nasıl bir şey yazdığımızı hatırlayın: önce yazdığımız her şey bellekte depolanır ve ardından flush() yöntemi çağrıldığında bellekteki arabellekteki tüm veriler diske yazılır. Bu flush() işlem taahhüdüdür.

Pekala, işlemin çalışması sırasında bir hata meydana gelirse, başlangıç ​​​​durumuna geri dönme sürecini başlatmanız gerekir. Bu işleme rollback() adı verilir ve bundan genellikle aynı adı taşıyan yöntem sorumludur.

Kabaca konuşursak, bir işlemi tamamlamanın 2 yolu vardır:

  • COMMIT - yapılan tüm değişiklikleri onaylıyoruz
  • ROLLBACK - yapılan tüm değişiklikleri geri alın

JDBC'deki işlemler

Hemen hemen her DBMS, işlemlerle çalışabilir. Yani JDBC'nin de bu durum için desteği var. Her şey çok basit bir şekilde uygulanır.

İlk olarak, Deyim nesnesinin icra() yöntemine yapılan her çağrı , ayrı bir işlemde yürütülür. Bunu yapmak için Connection'ın bir AutoCommit parametresi vardır . true olarak ayarlanırsa , commit( ) yöntemine yapılan her çağrıdan sonra çağrılacaktır .

İkinci olarak, bir işlemde birkaç komut yürütmek istiyorsanız, bunu şu şekilde yapabilirsiniz:

  • AutoCommit'i devre dışı bırak
  • komutlarımızı çağırmak
  • commit() yöntemini açıkça çağırın

Çok basit görünüyor:

connection.setAutoCommit(false);

Statement statement = connection.createStatement();
int rowsCount1 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
int rowsCount2 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
int rowsCount3 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");

connection.commit();

commit() yöntemi çalışırken sunucuda bir hata oluşursa SQL sunucusu üç eylemi de iptal eder.

Ancak istemci tarafında hatanın devam ettiği durumlar vardır ve commit() yöntem çağrısına hiçbir zaman ulaşamadık :

connection.setAutoCommit(false);

Statement statement = connection.createStatement();
int rowsCount1 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
int rowsCount2 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
int rowsCount3 = statement.executeUpdate("UPDATE multiple typos will result in an exception");

connection.commit();

Bir executeUpdate() yürütülürken bir hata oluşursa , commit() yöntemi çağrılmayacaktır. Yapılan tüm eylemleri geri almak için rollback() yöntemini çağırmanız gerekir . Genellikle şöyle görünür:

try{
  	connection.setAutoCommit(false);

  	Statement statement = connection.createStatement();
  	int rowsCount1 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
  	int rowsCount2 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
  	int rowsCount3 = statement.executeUpdate("UPDATE multiple typos will result in an exception");

	  connection.commit();
 }
 catch (Exception e) {
   connection.rollback();
}

kayıt noktaları

JDBC 3.0'ın gelişiyle, işlem geri alma ile daha verimli çalışmak mümkün hale geldi. Artık kaydetme noktalarını - kaydetme noktalarını ayarlayabilirsiniz ve geri alma () işlemini çağırdığınızda belirli bir kaydetme noktasına geri dönün.

Kaydetmek için bir kayıt noktası oluşturmanız gerekir, bu şu komutla yapılır:

Savepoint save = connection.setSavepoint();

Bir kayıt noktasına geri dönüş şu komutla yapılır:

connection.rollback(save);

Sorunlu komutumuzun önüne bir kayıt noktası eklemeyi deneyelim:

try{
  	connection.setAutoCommit(false);

  	Statement statement = connection.createStatement();
  	int rowsCount1 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");
  	int rowsCount2 = statement.executeUpdate("UPDATE  employee SET salary = salary+1000");

  	Savepoint save = connection.setSavepoint();
 	 try{
      	int rowsCount3 = statement.executeUpdate("UPDATE multiple typos will result in an exception");
 	 }
 	 catch (Exception e) {
    	   connection.rollback(save);
 	 }

	  connection.commit();
 }
 catch (Exception e) {
   connection.rollback();
}

Sorunlu yöntemi çağırmadan önce bir kaydetme noktası ekleyerek ve rollback(save) yöntemini çağırarak kaydedilmiş duruma dönerek iç içe işlemleri organize ettik .

Evet, oyunlarda kaydet/yükle'ye çok benzer.