জাভাতে ডাটাবেস সংযোগ বন্ধ হচ্ছে


121

আমি কিছুটা বিভ্রান্ত হয়ে যাচ্ছি, আমি http://en.wikedia.org/wiki/Java_Database_Connectivity থেকে নীচে পড়ছিলাম

Connection conn = DriverManager.getConnection(
     "jdbc:somejdbcvendor:other data needed by some jdbc vendor",
     "myLogin",
     "myPassword" );

Statement stmt = conn.createStatement();
try {
    stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " );
} finally {
    //It's important to close the statement when you are done with it
    stmt.close();
}

আপনার কি সংযোগটি বন্ধ করার দরকার নেই? সংযোগ বন্ধ () না ঘটলে আসলে কী ঘটছে?

আমার একটি বেসরকারী ওয়েব অ্যাপ্লিকেশন রয়েছে যা আমি বজায় করছি যা বর্তমানে কোনও ফর্মটি বন্ধ করে দেয় না, তবে গুরুত্বপূর্ণটি কি সত্যই স্ট্যামটি, সংযোগটি, বা উভয়ই?

সাইটটি মাঝেমধ্যে নিচে যেতে থাকে তবে সার্ভারটি বলে যে এটি একটি ডাটাবেস সংযোগের সমস্যা, আমার সন্দেহ হ'ল এটি বন্ধ হচ্ছে না তবে কোনটি বন্ধ করতে হবে তা আমি জানি না।


ক্লোজিং পরিচালনা করতে অন্য ড্রাইভার এবং টেম্পলেটগুলির উপর নির্ভর করে আপনার নিজের থেকে সংযোগগুলি বন্ধ করা সর্বদা সেরা অনুশীলন। সংযোগ বন্ধ করতে ব্যর্থ হওয়ার ফলে সকেটগুলি এবং সংস্থানগুলি ক্র্যাশ হওয়া অবধি (আর কোনও রিসোর্সের দৃশ্যমান হবে না) বা পুনরায় চালু না হওয়া পর্যন্ত চিরতরে খোলা থাকবে।
অরুণ জোশলা

উত্তর:


196

যখন আপনি নিজের ব্যবহারটি সম্পন্ন করেছেন Connection, আপনার close()অন্য কোনও ডাটাবেস সংস্থান (কার্সার, হ্যান্ডলস, ইত্যাদি) সংযোগটি ধরে রাখতে পারে তার জন্য তার পদ্ধতিটি কল করে স্পষ্টভাবে এটি বন্ধ করতে হবে।

প্রকৃতপক্ষে, জাভায় নিরাপদ নিদর্শনটি হ'ল আপনার ResultSet, Statementএবং Connection(সেই ক্রমে) কোনও finallyব্লকে আপনার যখন এটি করা হয় তখন বন্ধ করা something

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
    // Do stuff
    ...

} catch (SQLException ex) {
    // Exception handling stuff
    ...
} finally {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (ps != null) {
        try {
            ps.close();
        } catch (SQLException e) { /* ignored */}
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException e) { /* ignored */}
    }
}

finallyব্লক সামান্য (নাল চেক এড়াতে) মধ্যে উন্নত করা যেতে পারে:

} finally {
    try { rs.close(); } catch (Exception e) { /* ignored */ }
    try { ps.close(); } catch (Exception e) { /* ignored */ }
    try { conn.close(); } catch (Exception e) { /* ignored */ }
}

তবে, তবুও এটি অত্যন্ত ভার্চুয়াল তাই আপনি নাল-নিরাপদ সহায়ক পদ্ধতিগুলিতে অবজেক্টগুলি বন্ধ করতে একটি সহায়ক শ্রেণীর সাহায্যে শেষ করেন এবং finallyব্লকটি এরকম কিছু হয়ে যায়:

} finally {
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(ps);
    DbUtils.closeQuietly(conn);
}

এবং, প্রকৃতপক্ষে, অ্যাপাচি কমন্স DbUtils এর একটি DbUtilsবর্গ রয়েছে যা নিখুঁতভাবে এটি করছে যাতে আপনার নিজের লেখার দরকার নেই।


3
অসাধারণ সাহায্য, আপনাকে ধন্যবাদ! আমি এই সংযোগটি সম্পর্কে ধরা বা ভাবিনি! = নালামের বিবৃতি।
onaclov2000

1
@ onaclov2000 হ্যাঁ, rs, ps, connহতে পারে nullউপর যেখানে কোড বিরতি নির্ভর করে। এ কারণেই এটি "নিরাপদ" প্যাটার্ন হিসাবে পরিচিত।
পাস্কাল থিভেন্ট

12
@ প্যাসিকাল থিভেন্ট: আসলে আমাদের এগুলি সব বন্ধ করার দরকার নেই। "কোর জাভা ভলিউম টু - অ্যাডভান্সড ফিচারস" বইটি লিখেছেন: কোনও বিবরণের closeপদ্ধতি যদি বিবৃতিটির একটি মুক্ত ফলাফল সেট থাকে তবে Statementস্বয়ংক্রিয়ভাবে সম্পর্কিতটি বন্ধ করে দেয় ResultSet। একইভাবে, ক্লাসের closeপদ্ধতিটি Connectionসমস্তটি বন্ধ Statementsকরে দেয় Connection
মাজিদ আজিমি

12
@ মজিদ: যদি না এটি পুলের সংযোগ থাকে। বিবৃতিগুলি তখন ফুটো হয়ে যায়।
বালাসসি

1
@ বালুসসি: আপনি কি দয়া করে ব্যাখ্যা করতে পারেন যে যখন পুলের সংযোগ বন্ধ হয়ে যায় তখন কানেকশন.ক্লস () পদ্ধতিটি ব্যবহার করে
কৃষ্ণ চৈতন্য

61

ব্যবহারের পরে ডাটাবেস / রিসোর্স অবজেক্টগুলি বন্ধ করা সর্বদা ভাল। finallyব্লকের সংযোগ, ফলসেট এবং স্টেটমেন্ট অবজেক্টগুলি বন্ধ করা ভাল।

জাভা 7 অবধি, এই সমস্ত সংস্থানগুলি একটি finallyব্লক ব্যবহার করে বন্ধ করা দরকার । আপনি যদি জাভা 7 ব্যবহার করছেন, তবে সংস্থানগুলি বন্ধ করার জন্য আপনি নিম্নলিখিত হিসাবে করতে পারেন।

try(Connection con = getConnection(url, username, password, "org.postgresql.Driver");
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
) {

//statements
}catch(....){}

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

আশা করি আমি সহায়ক ছিলাম।


আমার বক্তব্য যদি অন্তর্নিহিত হয়, অর্থাত্ ব্লকের ResultSet rs = conn.createStatement().executeQuery(sql);ভিতরে try?
এন্টারেস 42

1
আপনি অবশেষে them} বন্ধের জন্য তাদের রেফারেন্স করতে পারবেন না। যদি কোনও ব্যতিক্রম নিক্ষেপ করা হয়, ফলাফল ফলাফলের ঘনিষ্ঠ () পদ্ধতিটি কখনই আর চাওয়া হবে না
ড্যান

আমি তাদের বন্ধ না করলে কী হবে?
অ্যালেক্স 78191

আপনি যদি এগুলি বন্ধ না করেন, তবে মেমরি ফাঁস হতে পারে।
ইয়াদু কৃষ্ণান

14

কেবলমাত্র Statementএবং বন্ধ করার জন্য এটি যথেষ্ট Connection। স্পষ্টভাবে ResultSetঅবজেক্টটি বন্ধ করার দরকার নেই ।

জাভা ডকুমেন্টেশন সম্পর্কে বলেছেন java.sql.ResultSet:

কোনও রেজাল্টসেট অবজেক্ট স্টেটমেন্ট অবজেক্ট দ্বারা স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায় যেটি যখন বিবৃতি অবজেক্টটি বন্ধ হয়ে যায়, পুনরায় কার্যকর করা হয় বা একাধিক ফলাফলের ক্রম থেকে পরবর্তী ফলাফল পুনরুদ্ধার করতে ব্যবহৃত হয় তখন তা তৈরি করে।


মন্তব্যের জন্য বালুসকে ধন্যবাদ: "আমি তার উপর নির্ভর করব না। কিছু জেডিবিসি ড্রাইভার তাতে ব্যর্থ হয়েছেন।"


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

1
আমি বরং এমন ড্রাইভার ব্যবহার করব না যা
চশমার

2
বালুসসি যেমন উল্লেখ করেছেন, নির্দিষ্ট সরবরাহকারীর উপর নির্ভরশীলতার উপর নির্ভরশীলতার পরিবর্তে স্পষ্টভাবে সংযোগটি বন্ধ করা ভাল প্রতিরক্ষামূলক প্রোগ্রামিং।
মাইকেলোকল

11

হ্যাঁ. আপনাকে ফলাফল সেট, বিবৃতি এবং সংযোগ বন্ধ করতে হবে। যদি সংযোগটি কোনও পুল থেকে আসে তবে এটি বন্ধ করলে তা এটিকে পুনরায় পুনরায় ব্যবহারের জন্য পুলটিতে প্রেরণ করে।

আপনাকে সাধারণত একটি finally{}ব্লকে এটি করতে হয়, যদি কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয়, আপনি এখনও এটি বন্ধ করার সুযোগ পাবেন।

অনেক ফ্রেমওয়ার্ক আপনার জন্য এই সংস্থান বরাদ্দ / অবলম্বন ইস্যুটি দেখাবে। উদাহরণস্বরূপ স্প্রিংয়ের জেডিবিসিটাইপলেটঅ্যাপাচি ডিবিইটিস- এর ফলাফল সেট / বিবৃতি / সংযোগটি শূন্য হোক বা না (এবং বন্ধ হওয়ার পরে ব্যতিক্রম ধরা পড়বে) বন্ধ করার তদারকি করার পদ্ধতি রয়েছে যা সাহায্য করতে পারে।


1
আমি যখন একটি "অবশেষে" গ্রহণ করি তখন এটি ভুল বলে আমাকে হাইলাইট করতে পছন্দ করে। এই ধরা ব্লক পরে যেতে হবে?
onaclov2000

হ্যাঁ. {} ধরা {} পরিশেষে পরখ করে দেখুন {}। ক্যাচ {} alচ্ছিক, বিটিডাব্লু। ঠিক শেষের মতো}}
ব্রায়ান অগ্নিউ

আমি "ঘনিষ্ঠ" বিবৃতিগুলি শেষ পর্যন্ত সরিয়েছি, তবে তারা কেবল "স্ক্লেক্সেসেপশন" বলছে, কোনও পরামর্শ?
onaclov2000

1
বন্ধ () একটি SQLException নিক্ষেপ। আপনি এটি পরিচালনা করতে হবে। এটিকে নিঃশব্দে পরিচালনা করতে DbUtils.closeQuietly () দেখুন।
ব্রায়ান অগ্নিউ

> সংযোগ বন্ধ () সংঘটিত না হলে আসলে কী ঘটছে?
অ্যালেক্স 78191

8

প্রকৃতপক্ষে, আপনি যদি চেষ্টা-ব্লক থেকে বেরিয়ে আসেন এবং আপনি জাভাস্ত্রের সাথে ব্লক ব্যবহার করে থাকেন এবং জাভা আপনার জন্য সমস্ত সংযোগ বন্ধ করে দেবে তবে এটি সর্বোত্তম।

অটোক্লোজেবল কার্যকর করে এমন কোনও বস্তুর সাথে আপনার এটি করা উচিত।

try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) {
    String sqlToExecute = "SELECT * FROM persons";
    try (ResultSet resultSet = statement.execute(sqlToExecute)) {
        if (resultSet.next()) {
            System.out.println(resultSet.getString("name");
        }
    }
} catch (SQLException e) {
    System.out.println("Failed to select persons.");
}

ডেট ডাটাবেস সংযোগে কলটি সবেমাত্র তৈরি হয়েছে। এটিকে এমন কোনও কলের সাথে প্রতিস্থাপন করুন যা আপনাকে একটি জেডিবিসি এসকিউএল সংযোগ বা কোনও পুলের সংযোগ দেয়।


সুতরাং আপনার এই ক্ষেত্রে ম্যানুয়ালি সংযোগ স্থাপন করতে হবে না?
কলিন ডি

1
সঠিক। আপনার স্পষ্টভাবে সংযোগটি বন্ধ করতে হবে না। চেষ্টা কোড ব্লকের সমাপ্তি এলে এটি বন্ধ হয়ে যাবে।
জো

7

হ্যাঁ, আপনাকে সংযোগটি বন্ধ করতে হবে। অন্যথায়, ডাটাবেস ক্লায়েন্ট সাধারণত সকেট সংযোগ এবং অন্যান্য সংস্থানগুলি উন্মুক্ত রাখে।


... যতক্ষণ না এটি বের হয় এটি ক্লায়েন্ট এবং সার্ভারের পক্ষের বিভিন্ন সসীম সংস্থানকে সংযুক্ত করে। যদি কোনও ক্লায়েন্ট এই ধরণের জিনিস অত্যধিক পরিমাণে করে থাকে তবে এটি ক্লায়েন্ট, ডাটাবেস পরিষেবা এবং সম্ভবত ক্লায়েন্ট বা সার্ভার মেশিনে চলমান অন্যান্য অ্যাপ্লিকেশনগুলির জন্যও সমস্যা তৈরি করতে পারে।
স্টিফেন সি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.