{"id":34011,"date":"2025-11-09T23:40:53","date_gmt":"2025-11-09T20:40:53","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=34011"},"modified":"2025-11-09T23:40:53","modified_gmt":"2025-11-09T20:40:53","slug":"spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/","title":{"rendered":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi"},"content":{"rendered":"<p><body><\/p>\n<h2>Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi<\/h2>\n<p>Spring Batch, kurumsal d\u00fczeyde g\u00fc\u00e7l\u00fc ve \u00f6l\u00e7eklenebilir batch uygulamalar\u0131 geli\u015ftirmek i\u00e7in tasarlanm\u0131\u015f a\u00e7\u0131k kaynakl\u0131 bir framework&#8217;t\u00fcr. Genellikle belirli bir zamanda, \u00e7ok say\u0131da veri kayd\u0131n\u0131 i\u00e7eren tekrarlayan g\u00f6revleri otomatikle\u015ftirmek i\u00e7in kullan\u0131l\u0131r. Bu t\u00fcr i\u015flemler, finansal raporlama, b\u00fcy\u00fck veri setlerinin migrasyonu, ETL (Extract, Transform, Load) s\u00fcre\u00e7leri, faturalama ve periyodik veri temizleme gibi alanlarda kritik \u00f6neme sahiptir. Spring Batch, bu karma\u015f\u0131k g\u00f6revleri y\u00f6netmek i\u00e7in sa\u011flam bir yap\u0131, hata y\u00f6netimi, yeniden ba\u015flat\u0131labilirlik ve izlenebilirlik gibi temel \u00f6zellikleri sunarak geli\u015ftiricilerin i\u015f y\u00fck\u00fcn\u00fc \u00f6nemli \u00f6l\u00e7\u00fcde hafifletir.<\/p>\n<p>Bu makalede, Spring Batch&#8217;in temel kavramlar\u0131n\u0131 derinlemesine inceleyecek, pratik bir \u00f6rnek \u00fczerinden ad\u0131m ad\u0131m bir batch uygulamas\u0131n\u0131n nas\u0131l olu\u015fturuldu\u011funu g\u00f6sterecek ve ard\u0131ndan framework&#8217;\u00fcn sundu\u011fu geli\u015fmi\u015f \u00f6zelliklere de\u011finece\u011fiz. Amac\u0131m\u0131z, Spring Batch&#8217;in b\u00fcy\u00fck veri i\u015flemlerini y\u00f6netme konusundaki g\u00fcc\u00fcn\u00fc ve esnekli\u011fini anlaman\u0131z\u0131 sa\u011flamakt\u0131r.<\/p>\n<h3>Spring Batch Temelleri<\/h3>\n<p>B\u00fcy\u00fck veri setleriyle \u00e7al\u0131\u015fmak, genellikle \u00e7evrimi\u00e7i (online) i\u015flemlere k\u0131yasla farkl\u0131 bir yakla\u015f\u0131m gerektirir. \u00c7evrimi\u00e7i i\u015flemler genellikle anl\u0131k, kullan\u0131c\u0131 odakl\u0131 ve k\u00fc\u00e7\u00fck veri par\u00e7ac\u0131klar\u0131 \u00fczerinde \u00e7al\u0131\u015f\u0131rken, batch i\u015flemleri arka planda, kullan\u0131c\u0131 etkile\u015fimi olmadan ve \u00e7ok daha b\u00fcy\u00fck veri hacimlerini i\u015flemek \u00fczere tasarlanm\u0131\u015ft\u0131r.<\/p>\n<h4>Batch \u0130\u015fleme Nedir?<\/h4>\n<p>Batch i\u015fleme, belirli bir zamanda toplanan veya biriktirilen bir grup i\u015flemi veya veriyi tek bir birim olarak i\u015fleme s\u00fcrecidir. Bu i\u015flemler genellikle insan m\u00fcdahalesi olmadan \u00e7al\u0131\u015f\u0131r ve kaynaklar\u0131n daha az yo\u011fun oldu\u011fu zamanlarda (\u00f6rne\u011fin gece saatleri) \u00e7al\u0131\u015ft\u0131r\u0131l\u0131r. Batch i\u015flemlerinin temel \u00f6zellikleri \u015funlard\u0131r:<\/p>\n<p>*   <strong>Tekrarlanabilirlik:<\/strong> Ayn\u0131 girdi verisiyle tekrar \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131nda ayn\u0131 sonucu \u00fcretmelidir.<br \/>\n*   <strong>Otomasyon:<\/strong> Manuel m\u00fcdahale olmadan \u00e7al\u0131\u015facak \u015fekilde tasarlanm\u0131\u015ft\u0131r.<br \/>\n*   <strong>B\u00fcy\u00fck Veri Hacmi:<\/strong> Milyonlarca kayd\u0131 i\u015fleyebilme kapasitesi.<br \/>\n*   <strong>Hata Tolerans\u0131:<\/strong> Bir hata durumunda i\u015flemi durdurabilme, hatay\u0131 kaydedebilme ve belirli bir noktadan yeniden ba\u015flatabilme yetene\u011fi.<br \/>\n*   <strong>\u0130zlenebilirlik:<\/strong> \u0130\u015flemin durumu, ilerlemesi ve sonu\u00e7lar\u0131 hakk\u0131nda bilgi sa\u011flayabilme.<\/p>\n<p>Kullan\u0131m alanlar\u0131na \u00f6rnek olarak bankac\u0131l\u0131kta g\u00fcn sonu i\u015flemleri, telekom\u00fcnikasyonda faturalama, e-ticarette stok g\u00fcncellemeleri veya rapor \u00fcretimi verilebilir.<\/p>\n<h4>Spring Batch Neden Kullan\u0131lmal\u0131?<\/h4>\n<p>Spring Batch, batch uygulamalar\u0131n\u0131n geli\u015ftirilmesinde kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 ele almak i\u00e7in tasarlanm\u0131\u015ft\u0131r. Geli\u015ftiricilere \u015fu avantajlar\u0131 sunar:<\/p>\n<p>*   <strong>Robustluk ve G\u00fcvenilirlik:<\/strong> \u0130\u015flemlerin hata durumunda dahi tutarl\u0131 kalmas\u0131n\u0131 sa\u011flar. Yeniden ba\u015flat\u0131labilirlik \u00f6zelli\u011fi sayesinde, kesintiye u\u011frayan bir i\u015flem en son ba\u015far\u0131l\u0131 noktadan devam edebilir.<br \/>\n*   <strong>\u00d6l\u00e7eklenebilirlik:<\/strong> B\u00fcy\u00fck veri hacimlerini i\u015flemek i\u00e7in \u00e7e\u015fitli stratejiler (paralel ad\u0131mlar, b\u00f6l\u00fcmlendirme, uzaktan y\u0131\u011f\u0131nlama) sunar.<br \/>\n*   <strong>Hata Y\u00f6netimi:<\/strong> Okuma, i\u015fleme ve yazma a\u015famalar\u0131nda meydana gelen hatalar\u0131 yakalama, atlama (skip) veya tekrar deneme (retry) mekanizmalar\u0131 sa\u011flar.<br \/>\n*   <strong>\u0130zlenebilirlik ve Y\u00f6netim:<\/strong> T\u00fcm batch i\u015flemlerinin meta verilerini (ba\u015flang\u0131\u00e7 zaman\u0131, biti\u015f zaman\u0131, durumu, ad\u0131m bilgileri vb.) bir veritaban\u0131nda saklar. Bu sayede i\u015flemlerin durumunu kolayca izlemek ve y\u00f6netmek m\u00fcmk\u00fcn olur.<br \/>\n*   <strong>Basitle\u015ftirilmi\u015f Geli\u015ftirme:<\/strong> \u00c7o\u011fu batch i\u015fleme senaryosunda tekrar eden (boilerplate) kodu ortadan kald\u0131r\u0131r ve geli\u015ftiricilerin i\u015f mant\u0131\u011f\u0131na odaklanmas\u0131n\u0131 sa\u011flar. Spring ekosistemiyle tam entegrasyon sunar.<\/p>\n<h4>Temel Kavramlar<\/h4>\n<p>Spring Batch&#8217;in mimarisi, belirli bir dizi temel kavram \u00fczerine kuruludur. Bu kavramlar\u0131 anlamak, etkili batch uygulamalar\u0131 geli\u015ftirmek i\u00e7in hayati \u00f6neme sahiptir.<\/p>\n<p>*   <strong>Job (\u0130\u015f):<\/strong> Bir batch i\u015fleminin tamam\u0131n\u0131 temsil eden ana birimdir. Bir <code>Job<\/code>, bir veya daha fazla <code>Step<\/code>&#8216;ten olu\u015fur. \u00d6rne\u011fin, &#8220;Kullan\u0131c\u0131 Verilerini Aktar&#8221; bir <code>Job<\/code> olabilir.<br \/>\n*   <strong>Step (Ad\u0131m):<\/strong> Bir <code>Job<\/code> i\u00e7indeki tekil, ba\u011f\u0131ms\u0131z bir a\u015famad\u0131r. Her <code>Step<\/code> kendi ba\u015f\u0131na bir g\u00f6revi yerine getirir. \u00d6rne\u011fin, &#8220;CSV Dosyas\u0131n\u0131 Oku&#8221;, &#8220;Veriyi Temizle&#8221;, &#8220;Veritaban\u0131na Yaz&#8221; ayr\u0131 birer <code>Step<\/code> olabilir.<br \/>\n*   <strong>JobInstance:<\/strong> Bir <code>Job<\/code>&#8216;\u0131n belirli bir \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131 temsil eder. Ayn\u0131 <code>Job<\/code>&#8216;\u0131 farkl\u0131 parametrelerle veya farkl\u0131 zamanlarda \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, her biri ayr\u0131 bir <code>JobInstance<\/code> olu\u015fturur.<br \/>\n*   <strong>JobExecution:<\/strong> Bir <code>JobInstance<\/code>&#8216;\u0131n tek bir \u00e7al\u0131\u015ft\u0131rma denemesidir. Bir <code>JobInstance<\/code> ba\u015far\u0131s\u0131z olursa ve yeniden ba\u015flat\u0131l\u0131rsa, yeni bir <code>JobExecution<\/code> olu\u015fturulur.<br \/>\n*   <strong>StepExecution:<\/strong> Bir <code>Step<\/code>&#8216;in tek bir \u00e7al\u0131\u015ft\u0131rma denemesidir. Her <code>JobExecution<\/code> i\u00e7inde birden fazla <code>StepExecution<\/code> bulunur.<br \/>\n*   <strong>ItemReader:<\/strong> Veriyi okuma sorumlulu\u011funu \u00fcstlenen bile\u015fendir. \u00c7e\u015fitli veri kaynaklar\u0131ndan (CSV, XML, veritaban\u0131, JMS kuyru\u011fu vb.) veri okuyabilir.<br \/>\n*   <strong>ItemProcessor:<\/strong> Okunan veriyi i\u015fleme, d\u00f6n\u00fc\u015ft\u00fcrme veya do\u011frulama sorumlulu\u011funu \u00fcstlenen iste\u011fe ba\u011fl\u0131 bir bile\u015fendir. <code>ItemReader<\/code>&#8216;dan okunan nesneyi al\u0131r, i\u015fler ve <code>ItemWriter<\/code>&#8216;a aktar\u0131lacak ba\u015fka bir nesne d\u00f6nd\u00fcr\u00fcr.<br \/>\n*   <strong>ItemWriter:<\/strong> \u0130\u015flenen veriyi kal\u0131c\u0131 bir depolama alan\u0131na (veritaban\u0131, dosya, JMS kuyru\u011fu vb.) yazma sorumlulu\u011funu \u00fcstlenen bile\u015fendir.<br \/>\n*   <strong>Chunk-Oriented Processing (Y\u0131\u011f\u0131n Odakl\u0131 \u0130\u015fleme):<\/strong> Spring Batch&#8217;in en yayg\u0131n <code>Step<\/code> t\u00fcr\u00fcd\u00fcr. Bu modelde, <code>ItemReader<\/code> belirli bir say\u0131da (y\u0131\u011f\u0131n boyutu &#8211; chunk size) \u00f6\u011feyi okur, <code>ItemProcessor<\/code> bu \u00f6\u011feleri i\u015fler ve <code>ItemWriter<\/code> i\u015flenen t\u00fcm \u00f6\u011feleri tek bir i\u015flem (transaction) i\u00e7inde yazar. Bu yakla\u015f\u0131m, performans ve kaynak y\u00f6netimi a\u00e7\u0131s\u0131ndan olduk\u00e7a etkilidir.<br \/>\n*   <strong>Tasklet:<\/strong> Basit, tek seferlik g\u00f6revleri yerine getirmek i\u00e7in kullan\u0131lan bir <code>Step<\/code> t\u00fcr\u00fcd\u00fcr. \u00d6rne\u011fin, bir dosya silme, bir SQL komutu \u00e7al\u0131\u015ft\u0131rma veya bir web servisi \u00e7a\u011f\u0131rma gibi g\u00f6revler i\u00e7in idealdir. <code>ItemReader<\/code>, <code>ItemProcessor<\/code>, <code>ItemWriter<\/code> d\u00f6ng\u00fcs\u00fcn\u00fc kullanmayan durumlarda tercih edilir.<br \/>\n*   <strong>JobLauncher:<\/strong> Bir <code>Job<\/code>&#8216;\u0131 ba\u015flatmak i\u00e7in kullan\u0131lan bir aray\u00fczd\u00fcr. Genellikle <code>JobParameters<\/code> ile birlikte bir <code>Job<\/code>&#8216;\u0131 tetikler.<br \/>\n*   <strong>JobRepository:<\/strong> T\u00fcm batch i\u015fleminin meta verilerini (JobInstance, JobExecution, StepExecution, JobParameters vb.) kal\u0131c\u0131 olarak saklayan anahtar bile\u015fendir. Bu, yeniden ba\u015flat\u0131labilirlik ve izlenebilirlik i\u00e7in gereklidir.<br \/>\n*   <strong>JobExplorer:<\/strong> <code>JobRepository<\/code>&#8216;de saklanan meta verilere salt okunur eri\u015fim sa\u011flar.<\/p>\n<h3>Bir Spring Batch \u00d6rne\u011fi Olu\u015fturma<\/h3>\n<p>\u015eimdi Spring Batch&#8217;in temel bile\u015fenlerini kullanarak basit bir batch uygulamas\u0131n\u0131 ad\u0131m ad\u0131m geli\u015ftirelim. Senaryomuz, bir CSV dosyas\u0131ndan kullan\u0131c\u0131 verilerini okumak, bu verileri i\u015flemek (\u00f6rne\u011fin e-posta adresini k\u00fc\u00e7\u00fck harfe \u00e7evirmek) ve ard\u0131ndan bir veritaban\u0131na kaydetmektir.<\/p>\n<h4>Proje Kurulumu<\/h4>\n<p>Spring Boot ile yeni bir proje olu\u015fturarak ba\u015flayaca\u011f\u0131z. Bunun i\u00e7in Spring Initializr (start.spring.io) kullanabiliriz.<br \/>\nGerekli ba\u011f\u0131ml\u0131l\u0131klar:<\/p>\n<p>*   <strong>Spring Batch:<\/strong> <code>spring-boot-starter-batch<\/code><br \/>\n*   <strong>Spring Data JPA:<\/strong> <code>spring-boot-starter-data-jpa<\/code> (veritaban\u0131na yazmak i\u00e7in)<br \/>\n*   <strong>H2 Database:<\/strong> <code>h2<\/code> (geli\u015ftirme ve \u00f6rnek i\u00e7in in-memory veritaban\u0131)<\/p>\n<pre><code class=\"language-xml\"><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 https:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0<\/modelVersion>\n    <parent>\n        <groupId>org.springframework.boot<\/groupId>\n        <artifactId>spring-boot-starter-parent<\/artifactId>\n        <version>3.2.5<\/version>\n        <relativePath\/> <!-- lookup parent from repository -->\n    <\/parent>\n    <groupId>com.example<\/groupId>\n    <artifactId>spring-batch-example<\/artifactId>\n    <version>0.0.1-SNAPSHOT<\/version>\n    <name>spring-batch-example<\/name>\n    <description>Spring Batch Example Project<\/description>\n    <properties>\n        <java.version>17<\/java.version>\n    <\/properties>\n    <dependencies>\n        <dependency>\n            <groupId>org.springframework.boot<\/groupId>\n            <artifactId>spring-boot-starter-batch<\/artifactId>\n        <\/dependency>\n        <dependency>\n            <groupId>org.springframework.boot<\/groupId>\n            <artifactId>spring-boot-starter-data-jpa<\/artifactId>\n        <\/dependency>\n        <dependency>\n            <groupId>com.h2database<\/groupId>\n            <artifactId>h2<\/artifactId>\n            <scope>runtime<\/scope>\n        <\/dependency>\n        <dependency>\n            <groupId>org.springframework.boot<\/groupId>\n            <artifactId>spring-boot-starter-test<\/artifactId>\n            <scope>test<\/scope>\n        <\/dependency>\n        <dependency>\n            <groupId>org.springframework.batch<\/groupId>\n            <artifactId>spring-batch-test<\/artifactId>\n            <scope>test<\/scope>\n        <\/dependency>\n    <\/dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.springframework.boot<\/groupId>\n                <artifactId>spring-boot-maven-plugin<\/artifactId>\n            <\/plugin>\n        <\/plugins>\n    <\/build>\n<\/project><\/code><\/pre>\n<h4>Veri Modeli Tan\u0131mlama<\/h4>\n<p>Kullan\u0131c\u0131 verilerini temsil edecek bir JPA varl\u0131\u011f\u0131 (entity) tan\u0131mlayal\u0131m.<\/p>\n<pre><code class=\"language-java\">package com.example.springbatchexample.model;\n\nimport jakarta.persistence.Entity;\nimport jakarta.persistence.GeneratedValue;\nimport jakarta.persistence.GenerationType;\nimport jakarta.persistence.Id;\nimport lombok.Data;\nimport lombok.NoArgsConstructor;\nimport lombok.AllArgsConstructor;\n\n@Entity\n@Data\n@NoArgsConstructor\n@AllArgsConstructor\npublic class User {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n    private String firstName;\n    private String lastName;\n    private String email;\n    private String status; \/\/ \u00d6rne\u011fin, ACTIVE, INACTIVE\n\n    \/\/ toString, equals, hashCode Lombok taraf\u0131ndan sa\u011flan\u0131r.\n}<\/code><\/pre>\n<p>Bu <code>User<\/code> varl\u0131\u011f\u0131n\u0131 kaydetmek i\u00e7in basit bir JPA deposu (repository) da olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-java\">package com.example.springbatchexample.repository;\n\nimport com.example.springbatchexample.model.User;\nimport org.springframework.data.jpa.repository.JpaRepository;\n\npublic interface UserRepository extends JpaRepository<User, Long> {\n}<\/code><\/pre>\n<h4>Job Tan\u0131mlama ve Yap\u0131land\u0131rma<\/h4>\n<p>Batch i\u015flemini yap\u0131land\u0131ran ana s\u0131n\u0131f\u0131 olu\u015ftural\u0131m. Bu s\u0131n\u0131f, <code>Job<\/code> ve <code>Step<\/code> bean&#8217;lerini tan\u0131mlayacakt\u0131r.<\/p>\n<pre><code class=\"language-java\">package com.example.springbatchexample.config;\n\nimport com.example.springbatchexample.model.User;\nimport com.example.springbatchexample.processor.UserItemProcessor;\nimport com.example.springbatchexample.repository.UserRepository;\nimport org.springframework.batch.core.Job;\nimport org.springframework.batch.core.Step;\nimport org.springframework.batch.core.job.builder.JobBuilder;\nimport org.springframework.batch.core.repository.JobRepository;\nimport org.springframework.batch.core.step.builder.StepBuilder;\nimport org.springframework.batch.item.data.RepositoryItemWriter;\nimport org.springframework.batch.item.file.FlatFileItemReader;\nimport org.springframework.batch.item.file.LineMapper;\nimport org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;\nimport org.springframework.batch.item.file.mapping.DefaultLineMapper;\nimport org.springframework.batch.item.file.transform.DelimitedLineTokenizer;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.io.ClassPathResource;\nimport org.springframework.transaction.PlatformTransactionManager;\n\n@Configuration\npublic class BatchConfig {\n\n    private final JobRepository jobRepository;\n    private final PlatformTransactionManager transactionManager;\n    private final UserRepository userRepository;\n\n    public BatchConfig(JobRepository jobRepository, PlatformTransactionManager transactionManager, UserRepository userRepository) {\n        this.jobRepository = jobRepository;\n        this.transactionManager = transactionManager;\n        this.userRepository = userRepository;\n    }\n\n    \/\/ ItemReader: CSV dosyas\u0131ndan veriyi okur\n    @Bean\n    public FlatFileItemReader<User> reader() {\n        FlatFileItemReader<User> itemReader = new FlatFileItemReader<>();\n        itemReader.setResource(new ClassPathResource(\"users.csv\")); \/\/ resources klas\u00f6r\u00fcndeki dosya\n        itemReader.setName(\"csvReader\");\n        itemReader.setLinesToSkip(1); \/\/ Ba\u015fl\u0131k sat\u0131r\u0131n\u0131 atla\n        itemReader.setLineMapper(lineMapper());\n        return itemReader;\n    }\n\n    @Bean\n    public LineMapper<User> lineMapper() {\n        DefaultLineMapper<User> lineMapper = new DefaultLineMapper<>();\n\n        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();\n        lineTokenizer.setDelimiter(\",\"); \/\/ CSV virg\u00fclle ayr\u0131lm\u0131\u015f\n        lineTokenizer.setStrict(false);\n        lineTokenizer.setNames(\"firstName\", \"lastName\", \"email\", \"status\"); \/\/ CSV'deki kolon adlar\u0131\n\n        BeanWrapperFieldSetMapper<User> fieldSetMapper = new BeanWrapperFieldSetMapper<>();\n        fieldSetMapper.setTargetType(User.class); \/\/ Hedef s\u0131n\u0131f\u0131m\u0131z User\n\n        lineMapper.setLineTokenizer(lineTokenizer);\n        lineMapper.setFieldSetMapper(fieldSetMapper);\n        return lineMapper;\n    }\n\n    \/\/ ItemProcessor: Okunan veriyi i\u015fler\/d\u00f6n\u00fc\u015ft\u00fcr\u00fcr\n    @Bean\n    public UserItemProcessor processor() {\n        return new UserItemProcessor();\n    }\n\n    \/\/ ItemWriter: \u0130\u015flenen veriyi veritaban\u0131na yazar\n    @Bean\n    public RepositoryItemWriter<User> writer() {\n        RepositoryItemWriter<User> writer = new RepositoryItemWriter<>();\n        writer.setRepository(userRepository);\n        writer.setMethodName(\"save\"); \/\/ UserRepository'deki save metodunu kullan\n        return writer;\n    }\n\n    \/\/ Step: Okuma -> \u0130\u015fleme -> Yazma ad\u0131m\u0131\n    @Bean\n    public Step importStep() {\n        return new StepBuilder(\"csvImportStep\", jobRepository)\n                .<User, User>chunk(10, transactionManager) \/\/ Her 10 kay\u0131tta bir commit et\n                .reader(reader())\n                .processor(processor())\n                .writer(writer())\n                .build();\n    }\n\n    \/\/ Job: T\u00fcm batch i\u015flemini tan\u0131mlar\n    @Bean\n    public Job importUserJob() {\n        return new JobBuilder(\"importUserJob\", jobRepository)\n                .flow(importStep())\n                .end()\n                .build();\n    }\n}<\/code><\/pre>\n<p>Uygulama s\u0131n\u0131f\u0131na <code>@EnableBatchProcessing<\/code> eklemeyi unutmay\u0131n:<\/p>\n<pre><code class=\"language-java\">package com.example.springbatchexample;\n\nimport org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n@SpringBootApplication\n@EnableBatchProcessing \/\/ Spring Batch \u00f6zelliklerini etkinle\u015ftirir\npublic class SpringBatchExampleApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(SpringBatchExampleApplication.class, args);\n    }\n}<\/code><\/pre>\n<h4>ItemReader Olu\u015fturma<\/h4>\n<p><code>BatchConfig<\/code> s\u0131n\u0131f\u0131nda <code>reader()<\/code> metodunu tan\u0131mlad\u0131k. Bu metod, <code>FlatFileItemReader<\/code> kullanarak <code>users.csv<\/code> dosyas\u0131n\u0131 okur.<br \/>\n*   <code>setResource(new ClassPathResource(\"users.csv\"))<\/code>: <code>src\/main\/resources<\/code> alt\u0131ndaki <code>users.csv<\/code> dosyas\u0131n\u0131 belirtir.<br \/>\n*   <code>setLinesToSkip(1)<\/code>: CSV dosyas\u0131n\u0131n ilk sat\u0131r\u0131n\u0131n ba\u015fl\u0131k oldu\u011funu varsayarak bu sat\u0131r\u0131 atlar.<br \/>\n*   <code>setLineMapper(lineMapper())<\/code>: Her sat\u0131r\u0131 <code>User<\/code> nesnesine nas\u0131l e\u015fleyece\u011fini belirten bir <code>LineMapper<\/code> kullan\u0131r.<br \/>\n    *   <code>DefaultLineMapper<\/code>: Sat\u0131r\u0131 token&#8217;lara ay\u0131rmak i\u00e7in <code>DelimitedLineTokenizer<\/code> ve bu token&#8217;lar\u0131 bir nesneye e\u015flemek i\u00e7in <code>BeanWrapperFieldSetMapper<\/code> kullan\u0131r.<br \/>\n    *   <code>DelimitedLineTokenizer<\/code>: Virg\u00fclle ayr\u0131lm\u0131\u015f (delimiter) alanlar\u0131 ay\u0131r\u0131r ve <code>firstName<\/code>, <code>lastName<\/code>, <code>email<\/code>, <code>status<\/code> adlar\u0131n\u0131 verir. Bu adlar <code>User<\/code> s\u0131n\u0131f\u0131ndaki alan adlar\u0131yla e\u015fle\u015fmelidir.<br \/>\n    *   <code>BeanWrapperFieldSetMapper<\/code>: Token&#8217;lar\u0131 <code>User<\/code> s\u0131n\u0131f\u0131n\u0131n ilgili alanlar\u0131na otomatik olarak e\u015fler.<\/p>\n<h4>ItemProcessor Olu\u015fturma<\/h4>\n<p><code>UserItemProcessor<\/code> s\u0131n\u0131f\u0131, <code>ItemProcessor<\/code> aray\u00fcz\u00fcn\u00fc implement eder ve okunan <code>User<\/code> nesnesi \u00fczerinde baz\u0131 d\u00f6n\u00fc\u015f\u00fcmler yapar. \u00d6rne\u011fin, e-posta adresini k\u00fc\u00e7\u00fck harfe \u00e7evirebiliriz.<\/p>\n<pre><code class=\"language-java\">package com.example.springbatchexample.processor;\n\nimport com.example.springbatchexample.model.User;\nimport org.springframework.batch.item.ItemProcessor;\n\npublic class UserItemProcessor implements ItemProcessor<User, User> {\n\n    @Override\n    public User process(User user) throws Exception {\n        \/\/ E-posta adresini k\u00fc\u00e7\u00fck harfe \u00e7evir\n        String processedEmail = user.getEmail().toLowerCase();\n        user.setEmail(processedEmail);\n        \/\/ \u0130simleri b\u00fcy\u00fck harfe \u00e7evirme gibi ba\u015fka i\u015flemler de yap\u0131labilir\n        user.setFirstName(user.getFirstName().toUpperCase());\n        user.setLastName(user.getLastName().toUpperCase());\n        \/\/ Durumu kontrol etme veya varsay\u0131lan de\u011fer atama\n        if (user.getStatus() == null || user.getStatus().isEmpty()) {\n            user.setStatus(\"ACTIVE\");\n        }\n        return user; \/\/ \u0130\u015flenmi\u015f User nesnesini d\u00f6nd\u00fcr\n    }\n}<\/code><\/pre>\n<h4>ItemWriter Olu\u015fturma<\/h4>\n<p><code>writer()<\/code> metodu, <code>RepositoryItemWriter<\/code> kullanarak i\u015flenen <code>User<\/code> nesnelerini <code>UserRepository<\/code> arac\u0131l\u0131\u011f\u0131yla veritaban\u0131na kaydeder.<br \/>\n*   <code>setRepository(userRepository)<\/code>: Kullan\u0131lacak JPA deposunu belirtir.<br \/>\n*   <code>setMethodName(\"save\")<\/code>: <code>UserRepository<\/code> \u00fczerindeki <code>save<\/code> metodunun \u00e7a\u011fr\u0131laca\u011f\u0131n\u0131 belirtir.<\/p>\n<h4>Job \u00c7al\u0131\u015ft\u0131rma ve Tetikleme<\/h4>\n<p>Batch i\u015flemini ba\u015flatmak i\u00e7in bir <code>CommandLineRunner<\/code> kullanabiliriz. Bu, uygulaman\u0131n ba\u015flad\u0131\u011f\u0131nda i\u015fi otomatik olarak tetikleyecektir.<\/p>\n<pre><code class=\"language-java\">package com.example.springbatchexample;\n\nimport org.springframework.batch.core.Job;\nimport org.springframework.batch.core.JobParameters;\nimport org.springframework.batch.core.JobParametersBuilder;\nimport org.springframework.batch.core.launch.JobLauncher;\nimport org.springframework.boot.CommandLineRunner;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class JobRunner implements CommandLineRunner {\n\n    private final JobLauncher jobLauncher;\n    private final Job importUserJob;\n\n    public JobRunner(JobLauncher jobLauncher, Job importUserJob) {\n        this.jobLauncher = jobLauncher;\n        this.importUserJob = importUserJob;\n    }\n\n    @Override\n    public void run(String... args) throws Exception {\n        \/\/ Her \u00e7al\u0131\u015ft\u0131rmada benzersiz bir JobParameters sa\u011flamak \u00f6nemlidir.\n        \/\/ Aksi takdirde, JobRepository ayn\u0131 JobInstance'\u0131 tekrar \u00e7al\u0131\u015ft\u0131rmaya \u00e7al\u0131\u015f\u0131r.\n        JobParameters jobParameters = new JobParametersBuilder()\n                .addLong(\"startAt\", System.currentTimeMillis())\n                .toJobParameters();\n\n        try {\n            jobLauncher.run(importUserJob, jobParameters);\n            System.out.println(\"Batch Job finished successfully!\");\n        } catch (Exception e) {\n            System.err.println(\"Batch Job failed: \" + e.getMessage());\n            e.printStackTrace();\n        }\n    }\n}<\/code><\/pre>\n<p><strong><code>JobParameters<\/code> \u00f6nemi:<\/strong> Spring Batch, bir <code>Job<\/code>&#8216;\u0131n ayn\u0131 <code>JobParameters<\/code> ile birden fazla kez \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131n\u0131 varsay\u0131lan olarak engeller. Bu, bir <code>JobInstance<\/code>&#8216;\u0131n benzersizli\u011fini sa\u011flar. Bu nedenle, her \u00e7al\u0131\u015ft\u0131rmada benzersiz bir parametre (\u00f6rne\u011fin, <code>System.currentTimeMillis()<\/code>) eklemek \u00f6nemlidir.<\/p>\n<h4>Uygulama Yap\u0131land\u0131rmas\u0131<\/h4>\n<p><code>src\/main\/resources\/application.properties<\/code> dosyas\u0131na H2 veritaban\u0131 ve Spring Batch i\u00e7in gerekli yap\u0131land\u0131rmalar\u0131 ekleyelim:<\/p>\n<pre><code class=\"language-properties\">spring.h2.console.enabled=true\nspring.h2.console.path=\/h2-console\nspring.datasource.url=jdbc:h2:mem:testdb\nspring.datasource.driverClassName=org.h2.Driver\nspring.datasource.username=sa\nspring.datasource.password=password\nspring.jpa.database-platform=org.hibernate.dialect.H2Dialect\nspring.jpa.hibernate.ddl-auto=update\n\n<h2>Spring Batch meta verilerini H2 veritaban\u0131nda sakla<\/h2>\nspring.batch.jdbc.initialize-schema=always\nlogging.level.org.springframework.batch=DEBUG<\/code><\/pre>\n<p><strong><code>users.csv<\/code> dosyas\u0131:<\/strong> <code>src\/main\/resources<\/code> klas\u00f6r\u00fcne a\u015fa\u011f\u0131daki gibi bir <code>users.csv<\/code> dosyas\u0131 ekleyin:<\/p>\n<pre><code class=\"language-csv\">firstName,lastName,email,status\nJohn,Doe,john.doe@example.com,ACTIVE\nJane,Smith,jane.smith@example.com,ACTIVE\nPeter,Jones,peter.jones@example.com,INACTIVE\nAlice,Williams,alice.williams@example.com,ACTIVE<\/code><\/pre>\n<p>Bu ad\u0131mlar\u0131 tamamlad\u0131ktan sonra uygulamay\u0131 \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131n\u0131zda, Spring Batch otomatik olarak <code>users.csv<\/code> dosyas\u0131n\u0131 okuyacak, verileri i\u015fleyecek ve H2 veritaban\u0131na kaydedecektir. H2 konsolunu (<code>http:\/\/localhost:8080\/h2-console<\/code>) kullanarak verilerin ba\u015far\u0131yla kaydedilip kaydedilmedi\u011fini kontrol edebilirsiniz.<\/p>\n<h3>Geli\u015fmi\u015f Spring Batch \u00d6zellikleri<\/h3>\n<p>Spring Batch sadece temel okuma-i\u015fleme-yazma d\u00f6ng\u00fcs\u00fcnden ibaret de\u011fildir; ayn\u0131 zamanda kurumsal d\u00fczeyde batch uygulamalar\u0131 i\u00e7in bir\u00e7ok geli\u015fmi\u015f \u00f6zellik sunar.<\/p>\n<h4>Hata Y\u00f6netimi ve Yeniden Ba\u015flat\u0131labilirlik<\/h4>\n<p>Batch i\u015flemlerinde hatalar ka\u00e7\u0131n\u0131lmazd\u0131r. Spring Batch, bu hatalar\u0131 zarif bir \u015fekilde y\u00f6netmek ve i\u015fleri kesintiye u\u011frad\u0131\u011f\u0131nda yeniden ba\u015flatmak i\u00e7in g\u00fc\u00e7l\u00fc mekanizmalar sunar.<\/p>\n<p>*   <strong><code>skip<\/code> ve <code>skipLimit<\/code>:<\/strong> <code>ItemReader<\/code>, <code>ItemProcessor<\/code> veya <code>ItemWriter<\/code> s\u0131ras\u0131nda belirli t\u00fcrdeki hatalar\u0131 atlamay\u0131 ve i\u015fleme devam etmeyi sa\u011flar. \u00d6rne\u011fin, bir CSV dosyas\u0131ndaki bozuk bir sat\u0131r\u0131 atlay\u0131p di\u011ferlerini i\u015flemeye devam edebilirsiniz. <code>skipLimit<\/code>, atlanabilecek maksimum hata say\u0131s\u0131n\u0131 belirler.<br \/>\n*   <strong><code>noRollbackFor<\/code>:<\/strong> Bir i\u015flem s\u0131ras\u0131nda belirli istisna t\u00fcrlerinin transaction&#8217;\u0131 geri almas\u0131n\u0131 engeller. Bu, belirli &#8220;i\u015f&#8221; istisnalar\u0131n\u0131 (\u00f6rne\u011fin, ge\u00e7ersiz bir kay\u0131t) bir hata olarak i\u015faretleyip i\u015flemi devam ettirmek istedi\u011finizde kullan\u0131\u015fl\u0131d\u0131r.<br \/>\n*   <strong><code>retry<\/code> ve <code>retryLimit<\/code>:<\/strong> Ge\u00e7ici hatalar (\u00f6rne\u011fin, veritaban\u0131 ba\u011flant\u0131 kesintisi) durumunda bir i\u015flemi otomatik olarak tekrar denemeyi sa\u011flar.<br \/>\n*   <strong>Yeniden Ba\u015flat\u0131labilirlik:<\/strong> <code>JobRepository<\/code>&#8216;nin sa\u011flad\u0131\u011f\u0131 en \u00f6nemli \u00f6zelliklerden biridir. Bir <code>JobExecution<\/code> ba\u015far\u0131s\u0131z oldu\u011funda veya manuel olarak durduruldu\u011funda, Spring Batch en son ba\u015far\u0131l\u0131 <code>Step<\/code>&#8216;ten veya <code>chunk<\/code>&#8216;tan i\u015fleme devam edebilir. Bu, uzun s\u00fcren batch i\u015flemlerinde zaman ve kaynak tasarrufu sa\u011flar.<\/p>\n<h4>Performans ve \u00d6l\u00e7eklenebilirlik<\/h4>\n<p>B\u00fcy\u00fck veri setleriyle \u00e7al\u0131\u015f\u0131rken performans kritik \u00f6neme sahiptir. Spring Batch, farkl\u0131 \u00f6l\u00e7eklenebilirlik stratejileri sunar:<\/p>\n<p>*   <strong><code>Chunk size<\/code> optimizasyonu:<\/strong> <code>chunk()<\/code> metoduyla belirtilen y\u0131\u011f\u0131n boyutu, performans \u00fczerinde b\u00fcy\u00fck etkiye sahiptir. Optimal bir y\u0131\u011f\u0131n boyutu, veritaban\u0131 commit&#8217;lerinin frekans\u0131n\u0131 ve bellek kullan\u0131m\u0131n\u0131 dengelemelidir.<br \/>\n*   <strong>Multi-threaded Step (Paralel Ad\u0131mlar):<\/strong> Bir <code>Step<\/code> i\u00e7indeki okuma, i\u015fleme ve yazma i\u015flemlerini birden fazla i\u015f par\u00e7ac\u0131\u011f\u0131nda paralel olarak \u00e7al\u0131\u015ft\u0131rmay\u0131 sa\u011flar. Bu, tek bir makinede CPU ve I\/O kaynaklar\u0131n\u0131n daha iyi kullan\u0131lmas\u0131n\u0131 sa\u011flar. <code>TaskExecutor<\/code> kullan\u0131larak yap\u0131land\u0131r\u0131l\u0131r.<br \/>\n*   <strong>Partitioning (B\u00f6l\u00fcmlendirme):<\/strong> Bir <code>Step<\/code>&#8216;in verisini mant\u0131ksal olarak birden fazla par\u00e7aya b\u00f6ler ve her par\u00e7ay\u0131 ayr\u0131 bir <code>StepExecution<\/code> olarak paralel \u00e7al\u0131\u015ft\u0131rmay\u0131 sa\u011flar. Bu, ayn\u0131 makinede veya farkl\u0131 makinelerde (uzak b\u00f6l\u00fcmlendirme) \u00e7al\u0131\u015ft\u0131r\u0131labilir. Veri setinin boyutuna g\u00f6re i\u015fi b\u00f6lmek i\u00e7in idealdir.<br \/>\n*   <strong>Remote Chunking (Uzaktan Y\u0131\u011f\u0131nlama):<\/strong> <code>ItemReader<\/code> ve <code>ItemProcessor<\/code>&#8216;\u0131n ana JVM&#8217;de \u00e7al\u0131\u015f\u0131rken, <code>ItemWriter<\/code>&#8216;\u0131n uzak bir i\u015f\u00e7iye (worker) devredildi\u011fi bir modeldir. Bu, yazma i\u015fleminin y\u00fcksek oranda \u00f6l\u00e7eklenebilir olmas\u0131n\u0131 sa\u011flar. Genellikle mesaj kuyruklar\u0131 (JMS, RabbitMQ, Kafka) kullan\u0131larak uygulan\u0131r.<\/p>\n<h4>Job Listener&#8217;lar<\/h4>\n<p>Spring Batch, bir <code>Job<\/code> veya <code>Step<\/code>&#8216;in ya\u015fam d\u00f6ng\u00fcs\u00fcndeki belirli olaylara (ba\u015flang\u0131\u00e7, biti\u015f, hata vb.) tepki vermek i\u00e7in listener&#8217;lar sa\u011flar.<\/p>\n<p>*   <strong><code>JobExecutionListener<\/code>:<\/strong> <code>Job<\/code> ba\u015flamadan \u00f6nce (<code>beforeJob<\/code>) ve bittikten sonra (<code>afterJob<\/code>) i\u015flemler yapmak i\u00e7in kullan\u0131l\u0131r. \u00d6rne\u011fin, bir i\u015f ba\u015flamadan \u00f6nce kaynaklar\u0131 haz\u0131rlamak veya bittikten sonra sonu\u00e7lar\u0131 raporlamak.<br \/>\n*   <strong><code>StepExecutionListener<\/code>:<\/strong> Benzer \u015fekilde, bir <code>Step<\/code> ba\u015flamadan \u00f6nce (<code>beforeStep<\/code>) ve bittikten sonra (<code>afterStep<\/code>) i\u015flemler yapmak i\u00e7in kullan\u0131l\u0131r.<br \/>\n*   <strong><code>ItemReadListener<\/code>, <code>ItemProcessListener<\/code>, <code>ItemWriteListener<\/code>:<\/strong> Okuma, i\u015fleme ve yazma a\u015famalar\u0131nda her bir \u00f6\u011fe veya y\u0131\u011f\u0131n \u00fczerinde olaylar\u0131 dinlemek i\u00e7in kullan\u0131l\u0131r. Hata durumlar\u0131n\u0131 yakalamak veya \u00f6zel loglama yapmak i\u00e7in faydal\u0131d\u0131r.<\/p>\n<pre><code class=\"language-java\">\/\/ \u00d6rnek JobExecutionListener\npackage com.example.springbatchexample.listener;\n\nimport org.springframework.batch.core.JobExecution;\nimport org.springframework.batch.core.JobExecutionListener;\nimport org.springframework.stereotype.Component;\n\n@Component\npublic class JobCompletionNotificationListener implements JobExecutionListener {\n\n    @Override\n    public void beforeJob(JobExecution jobExecution) {\n        System.out.println(\"!!! JOB STARTED! Time: \" + jobExecution.getStartTime());\n    }\n\n    @Override\n    public void afterJob(JobExecution jobExecution) {\n        if (jobExecution.getStatus().name().equals(\"COMPLETED\")) {\n            System.out.println(\"!!! JOB FINISHED! Time: \" + jobExecution.getEndTime());\n            System.out.println(\"Job Status: \" + jobExecution.getStatus());\n        } else {\n            System.out.println(\"!!! JOB FAILED! Time: \" + jobExecution.getEndTime());\n            System.out.println(\"Job Status: \" + jobExecution.getStatus());\n            System.out.println(\"Exit Status: \" + jobExecution.getExitStatus().getExitDescription());\n        }\n    }\n}<\/code><\/pre>\n<p>Bu listener&#8217;\u0131 <code>BatchConfig<\/code>&#8216;deki <code>importUserJob<\/code>&#8216;a eklemek i\u00e7in:<\/p>\n<pre><code class=\"language-java\">\/\/ BatchConfig s\u0131n\u0131f\u0131nda importUserJob bean'ini g\u00fcncelleyin\n@Bean\npublic Job importUserJob(JobCompletionNotificationListener listener) { \/\/ Listener'\u0131 parametre olarak al\u0131n\n    return new JobBuilder(\"importUserJob\", jobRepository)\n            .listener(listener) \/\/ Listener'\u0131 ekleyin\n            .flow(importStep())\n            .end()\n            .build();\n}<\/code><\/pre>\n<h4>Tasklet Kullan\u0131m\u0131<\/h4>\n<p><code>Tasklet<\/code>, <code>ItemReader<\/code>, <code>ItemProcessor<\/code>, <code>ItemWriter<\/code> d\u00f6ng\u00fcs\u00fcne uymayan basit g\u00f6revler i\u00e7in kullan\u0131l\u0131r. \u00d6rne\u011fin, bir batch i\u015flemi ba\u015flamadan \u00f6nce ge\u00e7ici dosyalar\u0131 temizlemek veya bittikten sonra bir e-posta g\u00f6ndermek gibi g\u00f6revler i\u00e7in idealdir.<\/p>\n<pre><code class=\"language-java\">\/\/ \u00d6rnek Tasklet\npackage com.example.springbatchexample.tasklet;\n\nimport org.springframework.batch.core.StepContribution;\nimport org.springframework.batch.core.scope.context.ChunkContext;\nimport org.springframework.batch.core.step.tasklet.Tasklet;\nimport org.springframework.batch.repeat.RepeatStatus;\nimport org.springframework.stereotype.Component;\n\nimport java.io.File;\n\n@Component\npublic class FileCleanupTasklet implements Tasklet {\n\n    private String filePath = \"temp_files\/\"; \/\/ Temizlenecek dosya yolu\n\n    @Override\n    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {\n        System.out.println(\"Cleaning up temporary files in: \" + filePath);\n        File directory = new File(filePath);\n        if (directory.exists() && directory.isDirectory()) {\n            File[] files = directory.listFiles();\n            if (files != null) {\n                for (File file : files) {\n                    if (file.delete()) {\n                        System.out.println(\"Deleted: \" + file.getName());\n                    } else {\n                        System.err.println(\"Failed to delete: \" + file.getName());\n                    }\n                }\n            }\n        } else {\n            System.out.println(\"Directory does not exist or is not a directory: \" + filePath);\n        }\n        return RepeatStatus.FINISHED;\n    }\n}<\/code><\/pre>\n<p>Bu tasklet&#8217;\u0131 bir <code>Step<\/code> olarak kullanmak i\u00e7in <code>BatchConfig<\/code>&#8216;e ekleyin:<\/p>\n<pre><code class=\"language-java\">\/\/ BatchConfig s\u0131n\u0131f\u0131nda\n@Bean\npublic Step cleanupStep(FileCleanupTasklet fileCleanupTasklet) {\n    return new StepBuilder(\"cleanupStep\", jobRepository)\n            .tasklet(fileCleanupTasklet, transactionManager)\n            .build();\n}\n\n@Bean\npublic Job importUserJob(JobCompletionNotificationListener listener, Step cleanupStep) { \/\/ cleanupStep'i de al\u0131n\n    return new JobBuilder(\"importUserJob\", jobRepository)\n            .listener(listener)\n            .flow(importStep())\n            .next(cleanupStep) \/\/ importStep'ten sonra cleanupStep'i \u00e7al\u0131\u015ft\u0131r\n            .end()\n            .build();\n}<\/code><\/pre>\n<h4>Veritaban\u0131 Deste\u011fi<\/h4>\n<p>\u00d6rne\u011fimizde H2 in-memory veritaban\u0131 kulland\u0131k. Ancak \u00fcretim ortamlar\u0131nda, <code>JobRepository<\/code>&#8216;nin meta verilerini kal\u0131c\u0131 olarak saklamak i\u00e7in PostgreSQL, MySQL, Oracle gibi kurumsal veritabanlar\u0131 kullan\u0131l\u0131r. <code>application.properties<\/code> dosyas\u0131nda veritaban\u0131 ba\u011flant\u0131 bilgilerini de\u011fi\u015ftirerek kolayca farkl\u0131 bir veritaban\u0131na ge\u00e7i\u015f yapabilirsiniz. Spring Batch, bu veritabanlar\u0131 i\u00e7in gerekli \u015femalar\u0131 otomatik olarak olu\u015fturur veya g\u00fcnceller (<code>spring.batch.jdbc.initialize-schema=always<\/code>).<\/p>\n<h3>Spring Batch Kullan\u0131m Senaryolar\u0131<\/h3>\n<p>Spring Batch&#8217;in sundu\u011fu esneklik ve g\u00fc\u00e7, onu \u00e7e\u015fitli kurumsal senaryolar i\u00e7in ideal bir \u00e7\u00f6z\u00fcm haline getirir:<\/p>\n<p>*   <strong>ETL (Extract, Transform, Load) S\u00fcre\u00e7leri:<\/strong> Farkl\u0131 kaynaklardan (dosyalar, veritabanlar\u0131, API&#8217;ler) veri \u00e7ekme, i\u015f kurallar\u0131na g\u00f6re d\u00f6n\u00fc\u015ft\u00fcrme ve hedef bir depoya (veri ambar\u0131, ba\u015fka bir veritaban\u0131) y\u00fckleme.<br \/>\n*   <strong>Finansal Raporlama:<\/strong> B\u00fcy\u00fck finansal i\u015flem kay\u0131tlar\u0131ndan \u00f6zet raporlar, bilan\u00e7o tablolar\u0131 veya gelir tablolar\u0131 olu\u015fturma.<br \/>\n*   <strong>B\u00fcy\u00fck Veri Setlerinin Migrasyonu:<\/strong> Eski bir sistemden yeni bir sisteme veya farkl\u0131 bir veritaban\u0131 \u015femas\u0131na milyonlarca kayd\u0131 g\u00fcvenli ve verimli bir \u015fekilde ta\u015f\u0131ma.<br \/>\n*   <strong>Faturalama ve \u00d6deme \u0130\u015flemleri:<\/strong> M\u00fc\u015fteri hesaplar\u0131n\u0131 i\u015fleme, faturalar olu\u015fturma, \u00f6demeleri kaydetme ve gecikmi\u015f \u00f6demeler i\u00e7in bildirimler g\u00f6nderme.<br \/>\n*   <strong>Veri Temizleme ve Do\u011frulama:<\/strong> Veri setlerindeki tutars\u0131zl\u0131klar\u0131, hatalar\u0131 veya eksik bilgileri tespit etme ve d\u00fczeltme. \u00d6rne\u011fin, yinelenen kay\u0131tlar\u0131 kald\u0131rma veya eksik adres bilgilerini tamamlama.<br \/>\n*   <strong>Stok Y\u00f6netimi:<\/strong> Belirli aral\u0131klarla stok seviyelerini g\u00fcncelleme, envanter say\u0131m\u0131 yapma ve d\u00fc\u015f\u00fck stok uyar\u0131lar\u0131 olu\u015fturma.<br \/>\n*   <strong>Toplu E-posta\/SMS G\u00f6nderimi:<\/strong> B\u00fcy\u00fck bir kullan\u0131c\u0131 listesine ki\u015fiselle\u015ftirilmi\u015f toplu e-postalar veya SMS bildirimleri g\u00f6nderme.<\/p>\n<p>Bu senaryolar\u0131n her biri, Spring Batch&#8217;in hata y\u00f6netimi, yeniden ba\u015flat\u0131labilirlik ve \u00f6l\u00e7eklenebilirlik \u00f6zelliklerinden \u00f6nemli \u00f6l\u00e7\u00fcde faydalan\u0131r.<\/p>\n<h3>Sonu\u00e7<\/h3>\n<p>Spring Batch, b\u00fcy\u00fck veri setlerini i\u015flemek i\u00e7in g\u00fc\u00e7l\u00fc, esnek ve kapsaml\u0131 bir framework sunar. Bu makalede, Spring Batch&#8217;in temel kavramlar\u0131n\u0131, bir CSV dosyas\u0131ndan veritaban\u0131na veri aktaran pratik bir \u00f6rne\u011fi ve framework&#8217;\u00fcn geli\u015fmi\u015f \u00f6zelliklerini (hata y\u00f6netimi, \u00f6l\u00e7eklenebilirlik, listener&#8217;lar, tasklet&#8217;lar) ele ald\u0131k.<\/p>\n<p>Spring Batch&#8217;in sundu\u011fu soyutlama katmanlar\u0131 sayesinde geli\u015ftiriciler, d\u00fc\u015f\u00fck seviyeli i\u015fleme detaylar\u0131 yerine i\u015f mant\u0131\u011f\u0131na odaklanabilirler. <code>JobRepository<\/code> arac\u0131l\u0131\u011f\u0131yla sa\u011flad\u0131\u011f\u0131 meta veri y\u00f6netimi, i\u015flemlerin izlenmesini, y\u00f6netilmesini ve hata durumunda sorunsuz bir \u015fekilde yeniden ba\u015flat\u0131lmas\u0131n\u0131 m\u00fcmk\u00fcn k\u0131lar.<\/p>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn veri yo\u011fun d\u00fcnyas\u0131nda, kurumsal uygulamalar genellikle milyonlarca kayd\u0131 i\u015fleme ihtiyac\u0131 duyar. Spring Batch, bu t\u00fcr zorlu batch i\u015fleme gereksinimlerini kar\u015f\u0131lamak i\u00e7in kan\u0131tlanm\u0131\u015f bir \u00e7\u00f6z\u00fcmd\u00fcr. Do\u011fru bir \u015fekilde uyguland\u0131\u011f\u0131nda, i\u015f s\u00fcre\u00e7lerinin otomasyonunu sa\u011flayarak verimlili\u011fi art\u0131r\u0131r, hatalar\u0131 azalt\u0131r ve i\u015fletmelerin b\u00fcy\u00fck veri setlerinden de\u011ferli i\u00e7g\u00f6r\u00fcler elde etmelerine yard\u0131mc\u0131 olur. Bu nedenle, modern kurumsal mimarilerin vazge\u00e7ilmez bir par\u00e7as\u0131 haline gelmi\u015ftir.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi\nSpring Batch, kurumsal d\u00fczeyde g\u00fc\u00e7l\u00fc ve \u00f6l\u00e7eklenebilir batch uygulamalar\u0131 geli\u015ft","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-34011","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi\" \/>\n<meta property=\"og:description\" content=\"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi Spring Batch, kurumsal d\u00fczeyde g\u00fc\u00e7l\u00fc ve \u00f6l\u00e7eklenebilir batch uygulamalar\u0131 geli\u015ft\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-09T20:40:53+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi\",\"datePublished\":\"2025-11-09T20:40:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\"},\"wordCount\":2589,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\",\"name\":\"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-09T20:40:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/","og_locale":"tr_TR","og_type":"article","og_title":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi","og_description":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi Spring Batch, kurumsal d\u00fczeyde g\u00fc\u00e7l\u00fc ve \u00f6l\u00e7eklenebilir batch uygulamalar\u0131 geli\u015ft","og_url":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-09T20:40:53+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"19 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi","datePublished":"2025-11-09T20:40:53+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/"},"wordCount":2589,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/","url":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/","name":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-09T20:40:53+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/spring-batch-ornegi-ile-buyuk-veri-islemleri-yonetimi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Spring Batch \u00d6rne\u011fi ile B\u00fcy\u00fck Veri \u0130\u015flemleri Y\u00f6netimi"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34011","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=34011"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34011\/revisions"}],"predecessor-version":[{"id":34012,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34011\/revisions\/34012"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=34011"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=34011"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=34011"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}