কেন লেনদেন প্রয়োজন

খুব প্রায়ই, একটি ডাটাবেসের সাথে কাজ করার সময়, একটি পরিস্থিতির উদ্ভব হয় যখন আপনাকে অনেকগুলি বিভিন্ন ক্রিয়া সম্পাদন করতে হবে, কিন্তু সেগুলি শুধুমাত্র একসাথে বোঝা যায়।

উদাহরণস্বরূপ, আমরা ব্যাংকিং সফ্টওয়্যার লিখছি যে তিনটি জিনিস করা উচিত:

  • গ্রাহকের অ্যাকাউন্ট থেকে টাকা উত্তোলন
  • প্রাপকের অ্যাকাউন্টে টাকা যোগ করুন
  • "পোস্টিং লগ" এ পোস্টিং ডেটা রেকর্ড করুন

যদি এই ক্রিয়াগুলির মধ্যে কোনওটি সম্পাদন করার সময় একটি ত্রুটি ঘটে, তবে অন্য দুটিকেও বাতিল করতে হবে। ক্লায়েন্টের কাছ থেকে টাকা কেটে নেওয়া এবং প্রাপকের কাছে যোগ করা অসম্ভব? আচ্ছা, বা প্রাপকের সাথে যোগ করুন, কিন্তু ক্লায়েন্ট থেকে বন্ধ লিখুন না?

সুতরাং, বিভিন্ন ক্রিয়াকে একটিতে এমন একটি যৌক্তিক গোষ্ঠীবদ্ধ করাকে লেনদেন বলা হয় । অন্য কথায়, একটি লেনদেন হল এমন একটি ক্রিয়াকলাপ যা শুধুমাত্র একসাথে করা উচিত । যদি কোনো ক্রিয়া ব্যর্থ হয় বা কোনো ত্রুটির সাথে সম্পাদিত হয়, তাহলে অন্য সব কর্ম বাতিল করতে হবে।

একটি লেনদেনের সাধারণত তিনটি অবস্থা থাকে:

  • প্রাথমিক অবস্থা - কর্মের একটি গ্রুপ চালানোর আগে সিস্টেমের অবস্থা
  • সাফল্য রাষ্ট্র - কর্ম গ্রুপ সম্পন্ন হওয়ার পরে রাষ্ট্র
  • ব্যর্থ রাষ্ট্র - কিছু ভুল হয়েছে

এই ক্ষেত্রে, সাধারণত তিনটি কমান্ড আছে:

  • start/start - লজিক্যাল গ্রুপ অফ অ্যাকশন শুরু হওয়ার আগে কার্যকর করা হয়
  • কমিট - লেনদেন অ্যাকশন গ্রুপের পরে কার্যকর করা হয়
  • রোলব্যাক - সিস্টেমটিকে ব্যর্থ অবস্থা থেকে প্রাথমিক অবস্থায় ফিরিয়ে আনার প্রক্রিয়া শুরু করে

এটা এই মত কাজ করে.

প্রথমে আপনাকে একটি লেনদেন খুলতে হবে - begin() বা start() পদ্ধতিতে কল করুন । এই পদ্ধতিতে কল করা সিস্টেমের অবস্থা নির্দেশ করে যেখানে কিছু ভুল হলে আমরা ফিরে আসার চেষ্টা করব।

তারপরে সমস্ত ক্রিয়া সঞ্চালিত হয়, যা একটি লজিক্যাল গ্রুপে একত্রিত হয় - একটি লেনদেন।

তারপর কমিট() পদ্ধতি বলা হয় । এর কল কর্মের একটি যৌক্তিক গোষ্ঠীর সমাপ্তি চিহ্নিত করে এবং সাধারণত এই ক্রিয়াগুলিকে অনুশীলনে রাখার প্রক্রিয়া শুরু করে।

মনে করুন কিভাবে আমরা ফাইল রাইটারে কিছু লিখেছি: প্রথমে, আমরা যা লিখেছি তা মেমরিতে সংরক্ষিত হয়, এবং তারপর যখন ফ্লাশ () পদ্ধতি বলা হয় , তখন মেমরির বাফার থেকে সমস্ত ডেটা ডিস্কে লেখা হয়। এই flush() হল লেনদেন কমিট।

ঠিক আছে, যদি লেনদেন পরিচালনার সময় একটি ত্রুটি ঘটে থাকে, তবে আপনাকে প্রারম্ভিক অবস্থায় ফিরে যাওয়ার প্রক্রিয়া শুরু করতে হবে। এই প্রক্রিয়াটিকে বলা হয় rollback() , এবং একই নামের পদ্ধতিটি সাধারণত এর জন্য দায়ী।

মোটামুটিভাবে বলতে গেলে, একটি লেনদেন সম্পূর্ণ করার 2টি উপায় রয়েছে:

  • কমিট - আমরা করা সমস্ত পরিবর্তন নিশ্চিত করি
  • রোলব্যাক - করা সমস্ত পরিবর্তন রোলব্যাক করুন৷

JDBC এ লেনদেন

প্রায় প্রতিটি DBMS লেনদেনের সাথে কাজ করতে পারে। তাই এই মামলায় জেডিবিসিরও সমর্থন রয়েছে। সবকিছু খুব সহজভাবে বাস্তবায়িত হয়।

প্রথমত, স্টেটমেন্ট অবজেক্টের execute() পদ্ধতিতে প্রতিটি কল একটি পৃথক লেনদেনে সম্পাদিত হয়। এটি করার জন্য, সংযোগের একটি অটোকমিট প্যারামিটার রয়েছে । যদি এটি true তে সেট করা হয় , তাহলে প্রতিটি কলের পর execute() পদ্ধতিতে কমিট() ডাকা হবে ।

দ্বিতীয়ত, আপনি যদি একটি লেনদেনে একাধিক কমান্ড চালাতে চান, তাহলে আপনি এটি এভাবে করতে পারেন:

  • অটোকমিট অক্ষম করুন
  • আমাদের কমান্ড কলিং
  • কমিট() পদ্ধতিটিকে স্পষ্টভাবে কল করুন

এটা খুব সহজ দেখায়:

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() পদ্ধতি চলাকালীন সার্ভারে যদি কোনো ত্রুটি ঘটে , তাহলে SQL সার্ভার তিনটি ক্রিয়াই বাতিল করবে।

কিন্তু এমন পরিস্থিতি রয়েছে যখন ত্রুটিটি এখনও ক্লায়েন্টের পক্ষ থেকে ঘটে এবং আমরা কখনই কমিট() পদ্ধতি কলে যাইনি :

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();

যদি একটি executeUpdate() কার্যকর করার সময় একটি ত্রুটি ঘটে , তাহলে কমিট() পদ্ধতিটি বলা হবে না। গৃহীত সমস্ত পদক্ষেপ রোল ব্যাক করতে, আপনাকে rollback() পদ্ধতিতে কল করতে হবে । এটি সাধারণত এই মত দেখায়:

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();
}

সেভপয়েন্ট

JDBC 3.0 এর আবির্ভাবের সাথে, লেনদেন রোলব্যাকের সাথে আরও দক্ষতার সাথে কাজ করা সম্ভব হয়েছে। এখন আপনি সেভ পয়েন্ট সেট করতে পারেন - পয়েন্টগুলি সংরক্ষণ করুন এবং আপনি যখন রোলব্যাক () অপারেশন কল করেন , তখন একটি নির্দিষ্ট সেভ পয়েন্টে ফিরে যান।

সংরক্ষণ করার জন্য, আপনাকে একটি সেভপয়েন্ট তৈরি করতে হবে, এটি কমান্ড দিয়ে করা হয়:

Savepoint save = connection.setSavepoint();

একটি সেভপয়েন্টে প্রত্যাবর্তন কমান্ড দিয়ে করা হয়:

connection.rollback(save);

আসুন আমাদের সমস্যাযুক্ত কমান্ডের আগে একটি সেভপয়েন্ট যোগ করার চেষ্টা করি:

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();
}

আমরা সমস্যাযুক্ত পদ্ধতিতে কল করার আগে একটি সেভ-পয়েন্ট যোগ করে নেস্টেড লেনদেন সংগঠিত করেছি এবং রোলব্যাক(সংরক্ষণ) পদ্ধতিতে কল করে সংরক্ষিত অবস্থায় ফিরে এসেছি ।

হ্যাঁ, এটি গেমগুলিতে সংরক্ষণ/লোড করার মতোই।